posterly-mcp-server 0.24.1 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +8 -2
  2. package/dist/generated/platform-manifest.d.ts +24 -24
  3. package/dist/generated/platform-manifest.js +30 -24
  4. package/dist/index.js +60 -0
  5. package/dist/lib/api-client.d.ts +66 -1
  6. package/dist/lib/api-client.js +26 -0
  7. package/dist/lib/version.d.ts +1 -1
  8. package/dist/lib/version.js +1 -1
  9. package/dist/tools/cancel-subscription.d.ts +30 -0
  10. package/dist/tools/cancel-subscription.js +41 -0
  11. package/dist/tools/create-api-key.d.ts +3 -3
  12. package/dist/tools/create-api-key.js +2 -2
  13. package/dist/tools/create-connect-session.d.ts +2 -2
  14. package/dist/tools/create-post.d.ts +27 -9
  15. package/dist/tools/create-post.js +1 -0
  16. package/dist/tools/create-posts-batch.d.ts +12 -5
  17. package/dist/tools/downgrade-subscription.d.ts +20 -0
  18. package/dist/tools/downgrade-subscription.js +23 -0
  19. package/dist/tools/get-connect-link.d.ts +2 -2
  20. package/dist/tools/get-platform-schema.d.ts +2 -2
  21. package/dist/tools/get-subscription.d.ts +8 -0
  22. package/dist/tools/get-subscription.js +26 -0
  23. package/dist/tools/get-updates.d.ts +24 -0
  24. package/dist/tools/get-updates.js +29 -0
  25. package/dist/tools/list-posts.d.ts +3 -3
  26. package/dist/tools/pause-subscription.d.ts +16 -0
  27. package/dist/tools/pause-subscription.js +21 -0
  28. package/dist/tools/resume-subscription.d.ts +8 -0
  29. package/dist/tools/resume-subscription.js +11 -0
  30. package/dist/tools/trigger-platform-helper.d.ts +3 -3
  31. package/dist/tools/update-post.d.ts +8 -0
  32. package/dist/tools/update-post.js +1 -0
  33. package/package.json +1 -1
  34. package/src/generated/platform-manifest.ts +30 -24
  35. package/src/index.ts +90 -0
  36. package/src/lib/api-client.ts +99 -1
  37. package/src/lib/version.ts +1 -1
  38. package/src/tools/cancel-subscription.ts +50 -0
  39. package/src/tools/create-api-key.ts +2 -2
  40. package/src/tools/create-post.ts +1 -0
  41. package/src/tools/downgrade-subscription.ts +29 -0
  42. package/src/tools/get-subscription.ts +31 -0
  43. package/src/tools/get-updates.ts +41 -0
  44. package/src/tools/pause-subscription.ts +26 -0
  45. package/src/tools/resume-subscription.ts +15 -0
  46. package/src/tools/update-post.ts +1 -0
package/README.md CHANGED
@@ -108,7 +108,7 @@ Add the same server definition to your Cursor MCP settings:
108
108
 
109
109
  ## Available tools
110
110
 
111
- `posterly-mcp-server@0.23.0` exposes 63 tools.
111
+ `posterly-mcp-server@0.26.0` exposes 73 tools.
112
112
 
113
113
  Public setup tools work before `POSTERLY_API_KEY` exists:
114
114
 
@@ -127,6 +127,11 @@ Authenticated tools require `POSTERLY_API_KEY`:
127
127
  - `get_connect_session` (poll connection progress while the user approves OAuth or enters credentials)
128
128
  - `create_api_key` (create a new API key after explicit confirmation; scopes cannot exceed the calling dashboard key)
129
129
  - `delete_api_key` (revoke a user-created API key after explicit confirmation)
130
+ - `get_subscription` (read subscription status, tier, and cancel/pause state; requires `billing:read`)
131
+ - `cancel_subscription` (cancel after explicit confirmation; the agent must ask for a `reason` first; requires `billing:write`)
132
+ - `pause_subscription` (pause 30 days, one per 90-day cooldown, after confirmation; requires `billing:write`)
133
+ - `resume_subscription` (resume a paused subscription; requires `billing:write`)
134
+ - `downgrade_subscription` (downgrade one tier at next renewal after confirmation; requires `billing:write`)
130
135
  - `list_oauth_clients`
131
136
  - `create_oauth_client` (create a public PKCE client after explicit confirmation)
132
137
  - `update_oauth_client` (update redirect URIs/scopes after explicit confirmation)
@@ -179,6 +184,7 @@ Authenticated tools require `POSTERLY_API_KEY`:
179
184
  > Google Business tip: pass `account_id` (the integer `id` from `list_accounts`) to every GBP tool. If you use `location_id` instead, it is the numeric `location_id` from `list_accounts` (the GBP location id), not the `ChIJ...` Place ID that `get_google_business_review_link` returns. Passing the Place ID resolves to no account and returns "Google Business Profile account not found".
180
185
 
181
186
  - `list_activity`
187
+ - `get_updates` (read the latest posterly product updates and news)
182
188
  - `list_webhooks`
183
189
  - `create_webhook` (create a webhook after explicit confirmation)
184
190
  - `update_webhook` (update a webhook after explicit confirmation)
@@ -235,7 +241,7 @@ This package uses the Posterly API/MCP add-on:
235
241
 
236
242
  - `$3/month` add-on
237
243
  - `100 create-post requests/hour` per API key, with separate media/read limits
238
- - user-created API keys per plan: Starter 1, Pro 2, Power User 3, Agency 4
244
+ - user-created API keys per plan: Starter 1, Pro 2, Power 3, Agency 4
239
245
  - works across all 17 supported platforms
240
246
 
241
247
  Each API call counts as one request, so use `create_posts_batch` when you need to schedule multiple posts in one confirmed operation.
@@ -1,9 +1,9 @@
1
1
  export declare const PLATFORM_MANIFEST: {
2
2
  readonly source: "lib/api-platform-registry.ts";
3
- readonly supportedPlatformIds: readonly ["instagram", "facebook", "tiktok", "twitter", "linkedin", "youtube", "pinterest", "threads", "google_business", "telegram", "bluesky", "discord", "mastodon", "devto", "hashnode", "wordpress", "lemmy"];
4
- readonly plannedPlatformIds: readonly ["reddit", "medium", "slack", "skool", "whop"];
5
- readonly allPlatformIds: readonly ["instagram", "facebook", "tiktok", "twitter", "linkedin", "youtube", "pinterest", "threads", "google_business", "telegram", "bluesky", "discord", "mastodon", "devto", "hashnode", "wordpress", "lemmy", "reddit", "medium", "slack", "skool", "whop"];
6
- readonly supportedPlatformInputs: readonly ["bluesky", "devto", "discord", "facebook", "gmb", "google-business", "google_business", "google_business_profile", "hashnode", "instagram", "instagram-standalone", "lemmy", "linkedin", "mastodon", "pinterest", "telegram", "threads", "tiktok", "twitter", "wordpress", "x", "youtube"];
3
+ readonly supportedPlatformIds: readonly ["instagram", "facebook", "tiktok", "twitter", "linkedin", "youtube", "pinterest", "threads", "google_business", "telegram", "bluesky", "discord", "slack", "mastodon", "devto", "hashnode", "wordpress", "lemmy"];
4
+ readonly plannedPlatformIds: readonly ["reddit", "medium", "skool", "whop"];
5
+ readonly allPlatformIds: readonly ["instagram", "facebook", "tiktok", "twitter", "linkedin", "youtube", "pinterest", "threads", "google_business", "telegram", "bluesky", "discord", "slack", "mastodon", "devto", "hashnode", "wordpress", "lemmy", "reddit", "medium", "skool", "whop"];
6
+ readonly supportedPlatformInputs: readonly ["bluesky", "devto", "discord", "facebook", "gmb", "google-business", "google_business", "google_business_profile", "hashnode", "instagram", "instagram-standalone", "lemmy", "linkedin", "mastodon", "pinterest", "slack", "telegram", "threads", "tiktok", "twitter", "wordpress", "x", "youtube"];
7
7
  readonly allPlatformInputs: readonly ["bluesky", "devto", "discord", "facebook", "gmb", "google-business", "google_business", "google_business_profile", "hashnode", "instagram", "instagram-standalone", "lemmy", "linkedin", "mastodon", "medium", "pinterest", "reddit", "skool", "slack", "telegram", "threads", "tiktok", "twitter", "whop", "wordpress", "x", "youtube"];
8
8
  readonly platformAliases: {
9
9
  readonly bluesky: "bluesky";
@@ -35,7 +35,7 @@ export declare const PLATFORM_MANIFEST: {
35
35
  };
36
36
  readonly helperNames: readonly ["linkedin.recent_mentions", "pinterest.boards", "tiktok.creator_info", "x.quota"];
37
37
  readonly analyticsPlatformIds: readonly ["instagram", "facebook", "linkedin", "youtube", "pinterest", "threads", "google_business"];
38
- readonly connectTargetIds: readonly ["instagram", "meta", "facebook", "youtube", "tiktok", "linkedin", "linkedin_page", "threads", "google_business", "pinterest", "twitter", "telegram", "bluesky", "discord", "mastodon", "devto", "hashnode", "wordpress", "lemmy", "reddit", "medium", "slack", "skool", "whop"];
38
+ readonly connectTargetIds: readonly ["instagram", "meta", "facebook", "youtube", "tiktok", "linkedin", "linkedin_page", "threads", "google_business", "pinterest", "twitter", "telegram", "bluesky", "discord", "slack", "mastodon", "devto", "hashnode", "wordpress", "lemmy", "reddit", "medium", "skool", "whop"];
39
39
  readonly connectInputs: readonly ["bluesky", "devto", "discord", "facebook", "facebook_instagram", "facebook_pages", "gmb", "google-business", "google_business", "google_business_profile", "hashnode", "instagram", "instagram-standalone", "instagram_direct", "lemmy", "linkedin", "linkedin-company", "linkedin-page", "linkedin_company", "linkedin_page", "linkedin_personal", "mastodon", "medium", "meta", "meta_business", "pinterest", "reddit", "skool", "slack", "telegram", "threads", "tiktok", "twitter", "whop", "wordpress", "x", "x_twitter", "youtube"];
40
40
  readonly connectAliases: {
41
41
  readonly bluesky: "bluesky";
@@ -170,6 +170,14 @@ export declare const PLATFORM_MANIFEST: {
170
170
  readonly postTypes: readonly ["text", "image", "video", "carousel"];
171
171
  readonly analyticsSupported: false;
172
172
  readonly helpers: readonly [];
173
+ }, {
174
+ readonly id: "slack";
175
+ readonly label: "Slack";
176
+ readonly status: "supported";
177
+ readonly aliases: readonly [];
178
+ readonly postTypes: readonly ["text", "image", "video", "carousel"];
179
+ readonly analyticsSupported: false;
180
+ readonly helpers: readonly [];
173
181
  }, {
174
182
  readonly id: "mastodon";
175
183
  readonly label: "Mastodon";
@@ -226,14 +234,6 @@ export declare const PLATFORM_MANIFEST: {
226
234
  readonly postTypes: readonly [];
227
235
  readonly analyticsSupported: false;
228
236
  readonly helpers: readonly [];
229
- }, {
230
- readonly id: "slack";
231
- readonly label: "Slack";
232
- readonly status: "planned";
233
- readonly aliases: readonly [];
234
- readonly postTypes: readonly [];
235
- readonly analyticsSupported: false;
236
- readonly helpers: readonly [];
237
237
  }, {
238
238
  readonly id: "skool";
239
239
  readonly label: "Skool";
@@ -335,6 +335,12 @@ export declare const PLATFORM_MANIFEST: {
335
335
  readonly status: "supported";
336
336
  readonly aliases: readonly [];
337
337
  readonly method: "manual_credentials";
338
+ }, {
339
+ readonly id: "slack";
340
+ readonly label: "Slack";
341
+ readonly status: "supported";
342
+ readonly aliases: readonly [];
343
+ readonly method: "dashboard_oauth";
338
344
  }, {
339
345
  readonly id: "mastodon";
340
346
  readonly label: "Mastodon";
@@ -377,12 +383,6 @@ export declare const PLATFORM_MANIFEST: {
377
383
  readonly status: "planned";
378
384
  readonly aliases: readonly [];
379
385
  readonly method: "planned";
380
- }, {
381
- readonly id: "slack";
382
- readonly label: "Slack";
383
- readonly status: "planned";
384
- readonly aliases: readonly [];
385
- readonly method: "planned";
386
386
  }, {
387
387
  readonly id: "skool";
388
388
  readonly label: "Skool";
@@ -397,12 +397,12 @@ export declare const PLATFORM_MANIFEST: {
397
397
  readonly method: "planned";
398
398
  }];
399
399
  };
400
- export declare const SUPPORTED_PLATFORM_IDS: readonly ["instagram", "facebook", "tiktok", "twitter", "linkedin", "youtube", "pinterest", "threads", "google_business", "telegram", "bluesky", "discord", "mastodon", "devto", "hashnode", "wordpress", "lemmy"];
401
- export declare const PLANNED_PLATFORM_IDS: readonly ["reddit", "medium", "slack", "skool", "whop"];
402
- export declare const ALL_PLATFORM_IDS: readonly ["instagram", "facebook", "tiktok", "twitter", "linkedin", "youtube", "pinterest", "threads", "google_business", "telegram", "bluesky", "discord", "mastodon", "devto", "hashnode", "wordpress", "lemmy", "reddit", "medium", "slack", "skool", "whop"];
403
- export declare const SUPPORTED_PLATFORM_INPUTS: readonly ["bluesky", "devto", "discord", "facebook", "gmb", "google-business", "google_business", "google_business_profile", "hashnode", "instagram", "instagram-standalone", "lemmy", "linkedin", "mastodon", "pinterest", "telegram", "threads", "tiktok", "twitter", "wordpress", "x", "youtube"];
400
+ export declare const SUPPORTED_PLATFORM_IDS: readonly ["instagram", "facebook", "tiktok", "twitter", "linkedin", "youtube", "pinterest", "threads", "google_business", "telegram", "bluesky", "discord", "slack", "mastodon", "devto", "hashnode", "wordpress", "lemmy"];
401
+ export declare const PLANNED_PLATFORM_IDS: readonly ["reddit", "medium", "skool", "whop"];
402
+ export declare const ALL_PLATFORM_IDS: readonly ["instagram", "facebook", "tiktok", "twitter", "linkedin", "youtube", "pinterest", "threads", "google_business", "telegram", "bluesky", "discord", "slack", "mastodon", "devto", "hashnode", "wordpress", "lemmy", "reddit", "medium", "skool", "whop"];
403
+ export declare const SUPPORTED_PLATFORM_INPUTS: readonly ["bluesky", "devto", "discord", "facebook", "gmb", "google-business", "google_business", "google_business_profile", "hashnode", "instagram", "instagram-standalone", "lemmy", "linkedin", "mastodon", "pinterest", "slack", "telegram", "threads", "tiktok", "twitter", "wordpress", "x", "youtube"];
404
404
  export declare const ALL_PLATFORM_INPUTS: readonly ["bluesky", "devto", "discord", "facebook", "gmb", "google-business", "google_business", "google_business_profile", "hashnode", "instagram", "instagram-standalone", "lemmy", "linkedin", "mastodon", "medium", "pinterest", "reddit", "skool", "slack", "telegram", "threads", "tiktok", "twitter", "whop", "wordpress", "x", "youtube"];
405
405
  export declare const PLATFORM_HELPER_NAMES: readonly ["linkedin.recent_mentions", "pinterest.boards", "tiktok.creator_info", "x.quota"];
406
- export declare const CONNECT_TARGET_IDS: readonly ["instagram", "meta", "facebook", "youtube", "tiktok", "linkedin", "linkedin_page", "threads", "google_business", "pinterest", "twitter", "telegram", "bluesky", "discord", "mastodon", "devto", "hashnode", "wordpress", "lemmy", "reddit", "medium", "slack", "skool", "whop"];
406
+ export declare const CONNECT_TARGET_IDS: readonly ["instagram", "meta", "facebook", "youtube", "tiktok", "linkedin", "linkedin_page", "threads", "google_business", "pinterest", "twitter", "telegram", "bluesky", "discord", "slack", "mastodon", "devto", "hashnode", "wordpress", "lemmy", "reddit", "medium", "skool", "whop"];
407
407
  export declare const CONNECT_INPUTS: readonly ["bluesky", "devto", "discord", "facebook", "facebook_instagram", "facebook_pages", "gmb", "google-business", "google_business", "google_business_profile", "hashnode", "instagram", "instagram-standalone", "instagram_direct", "lemmy", "linkedin", "linkedin-company", "linkedin-page", "linkedin_company", "linkedin_page", "linkedin_personal", "mastodon", "medium", "meta", "meta_business", "pinterest", "reddit", "skool", "slack", "telegram", "threads", "tiktok", "twitter", "whop", "wordpress", "x", "x_twitter", "youtube"];
408
408
  export declare const ANALYTICS_PLATFORM_IDS: readonly ["instagram", "facebook", "linkedin", "youtube", "pinterest", "threads", "google_business"];
@@ -14,6 +14,7 @@ export const PLATFORM_MANIFEST = {
14
14
  "telegram",
15
15
  "bluesky",
16
16
  "discord",
17
+ "slack",
17
18
  "mastodon",
18
19
  "devto",
19
20
  "hashnode",
@@ -23,7 +24,6 @@ export const PLATFORM_MANIFEST = {
23
24
  "plannedPlatformIds": [
24
25
  "reddit",
25
26
  "medium",
26
- "slack",
27
27
  "skool",
28
28
  "whop"
29
29
  ],
@@ -40,6 +40,7 @@ export const PLATFORM_MANIFEST = {
40
40
  "telegram",
41
41
  "bluesky",
42
42
  "discord",
43
+ "slack",
43
44
  "mastodon",
44
45
  "devto",
45
46
  "hashnode",
@@ -47,7 +48,6 @@ export const PLATFORM_MANIFEST = {
47
48
  "lemmy",
48
49
  "reddit",
49
50
  "medium",
50
- "slack",
51
51
  "skool",
52
52
  "whop"
53
53
  ],
@@ -67,6 +67,7 @@ export const PLATFORM_MANIFEST = {
67
67
  "linkedin",
68
68
  "mastodon",
69
69
  "pinterest",
70
+ "slack",
70
71
  "telegram",
71
72
  "threads",
72
73
  "tiktok",
@@ -162,6 +163,7 @@ export const PLATFORM_MANIFEST = {
162
163
  "telegram",
163
164
  "bluesky",
164
165
  "discord",
166
+ "slack",
165
167
  "mastodon",
166
168
  "devto",
167
169
  "hashnode",
@@ -169,7 +171,6 @@ export const PLATFORM_MANIFEST = {
169
171
  "lemmy",
170
172
  "reddit",
171
173
  "medium",
172
- "slack",
173
174
  "skool",
174
175
  "whop"
175
176
  ],
@@ -435,6 +436,20 @@ export const PLATFORM_MANIFEST = {
435
436
  "analyticsSupported": false,
436
437
  "helpers": []
437
438
  },
439
+ {
440
+ "id": "slack",
441
+ "label": "Slack",
442
+ "status": "supported",
443
+ "aliases": [],
444
+ "postTypes": [
445
+ "text",
446
+ "image",
447
+ "video",
448
+ "carousel"
449
+ ],
450
+ "analyticsSupported": false,
451
+ "helpers": []
452
+ },
438
453
  {
439
454
  "id": "mastodon",
440
455
  "label": "Mastodon",
@@ -515,15 +530,6 @@ export const PLATFORM_MANIFEST = {
515
530
  "analyticsSupported": false,
516
531
  "helpers": []
517
532
  },
518
- {
519
- "id": "slack",
520
- "label": "Slack",
521
- "status": "planned",
522
- "aliases": [],
523
- "postTypes": [],
524
- "analyticsSupported": false,
525
- "helpers": []
526
- },
527
533
  {
528
534
  "id": "skool",
529
535
  "label": "Skool",
@@ -663,6 +669,13 @@ export const PLATFORM_MANIFEST = {
663
669
  "aliases": [],
664
670
  "method": "manual_credentials"
665
671
  },
672
+ {
673
+ "id": "slack",
674
+ "label": "Slack",
675
+ "status": "supported",
676
+ "aliases": [],
677
+ "method": "dashboard_oauth"
678
+ },
666
679
  {
667
680
  "id": "mastodon",
668
681
  "label": "Mastodon",
@@ -712,13 +725,6 @@ export const PLATFORM_MANIFEST = {
712
725
  "aliases": [],
713
726
  "method": "planned"
714
727
  },
715
- {
716
- "id": "slack",
717
- "label": "Slack",
718
- "status": "planned",
719
- "aliases": [],
720
- "method": "planned"
721
- },
722
728
  {
723
729
  "id": "skool",
724
730
  "label": "Skool",
@@ -735,12 +741,12 @@ export const PLATFORM_MANIFEST = {
735
741
  }
736
742
  ]
737
743
  };
738
- export const SUPPORTED_PLATFORM_IDS = ["instagram", "facebook", "tiktok", "twitter", "linkedin", "youtube", "pinterest", "threads", "google_business", "telegram", "bluesky", "discord", "mastodon", "devto", "hashnode", "wordpress", "lemmy"];
739
- export const PLANNED_PLATFORM_IDS = ["reddit", "medium", "slack", "skool", "whop"];
740
- export const ALL_PLATFORM_IDS = ["instagram", "facebook", "tiktok", "twitter", "linkedin", "youtube", "pinterest", "threads", "google_business", "telegram", "bluesky", "discord", "mastodon", "devto", "hashnode", "wordpress", "lemmy", "reddit", "medium", "slack", "skool", "whop"];
741
- export const SUPPORTED_PLATFORM_INPUTS = ["bluesky", "devto", "discord", "facebook", "gmb", "google-business", "google_business", "google_business_profile", "hashnode", "instagram", "instagram-standalone", "lemmy", "linkedin", "mastodon", "pinterest", "telegram", "threads", "tiktok", "twitter", "wordpress", "x", "youtube"];
744
+ export const SUPPORTED_PLATFORM_IDS = ["instagram", "facebook", "tiktok", "twitter", "linkedin", "youtube", "pinterest", "threads", "google_business", "telegram", "bluesky", "discord", "slack", "mastodon", "devto", "hashnode", "wordpress", "lemmy"];
745
+ export const PLANNED_PLATFORM_IDS = ["reddit", "medium", "skool", "whop"];
746
+ export const ALL_PLATFORM_IDS = ["instagram", "facebook", "tiktok", "twitter", "linkedin", "youtube", "pinterest", "threads", "google_business", "telegram", "bluesky", "discord", "slack", "mastodon", "devto", "hashnode", "wordpress", "lemmy", "reddit", "medium", "skool", "whop"];
747
+ export const SUPPORTED_PLATFORM_INPUTS = ["bluesky", "devto", "discord", "facebook", "gmb", "google-business", "google_business", "google_business_profile", "hashnode", "instagram", "instagram-standalone", "lemmy", "linkedin", "mastodon", "pinterest", "slack", "telegram", "threads", "tiktok", "twitter", "wordpress", "x", "youtube"];
742
748
  export const ALL_PLATFORM_INPUTS = ["bluesky", "devto", "discord", "facebook", "gmb", "google-business", "google_business", "google_business_profile", "hashnode", "instagram", "instagram-standalone", "lemmy", "linkedin", "mastodon", "medium", "pinterest", "reddit", "skool", "slack", "telegram", "threads", "tiktok", "twitter", "whop", "wordpress", "x", "youtube"];
743
749
  export const PLATFORM_HELPER_NAMES = ["linkedin.recent_mentions", "pinterest.boards", "tiktok.creator_info", "x.quota"];
744
- export const CONNECT_TARGET_IDS = ["instagram", "meta", "facebook", "youtube", "tiktok", "linkedin", "linkedin_page", "threads", "google_business", "pinterest", "twitter", "telegram", "bluesky", "discord", "mastodon", "devto", "hashnode", "wordpress", "lemmy", "reddit", "medium", "slack", "skool", "whop"];
750
+ export const CONNECT_TARGET_IDS = ["instagram", "meta", "facebook", "youtube", "tiktok", "linkedin", "linkedin_page", "threads", "google_business", "pinterest", "twitter", "telegram", "bluesky", "discord", "slack", "mastodon", "devto", "hashnode", "wordpress", "lemmy", "reddit", "medium", "skool", "whop"];
745
751
  export const CONNECT_INPUTS = ["bluesky", "devto", "discord", "facebook", "facebook_instagram", "facebook_pages", "gmb", "google-business", "google_business", "google_business_profile", "hashnode", "instagram", "instagram-standalone", "instagram_direct", "lemmy", "linkedin", "linkedin-company", "linkedin-page", "linkedin_company", "linkedin_page", "linkedin_personal", "mastodon", "medium", "meta", "meta_business", "pinterest", "reddit", "skool", "slack", "telegram", "threads", "tiktok", "twitter", "whop", "wordpress", "x", "x_twitter", "youtube"];
746
752
  export const ANALYTICS_PLATFORM_IDS = ["instagram", "facebook", "linkedin", "youtube", "pinterest", "threads", "google_business"];
package/dist/index.js CHANGED
@@ -50,6 +50,7 @@ import { listGoogleBusinessMediaTool } from './tools/list-google-business-media.
50
50
  import { addGoogleBusinessMediaTool } from './tools/add-google-business-media.js';
51
51
  import { deleteGoogleBusinessMediaTool } from './tools/delete-google-business-media.js';
52
52
  import { listActivityTool } from './tools/list-activity.js';
53
+ import { getUpdatesTool } from './tools/get-updates.js';
53
54
  import { listWebhooksTool } from './tools/list-webhooks.js';
54
55
  import { createWebhookTool } from './tools/create-webhook.js';
55
56
  import { updateWebhookTool } from './tools/update-webhook.js';
@@ -66,6 +67,11 @@ import { createConnectSessionTool } from './tools/create-connect-session.js';
66
67
  import { getConnectSessionTool } from './tools/get-connect-session.js';
67
68
  import { createApiKeyTool } from './tools/create-api-key.js';
68
69
  import { deleteApiKeyTool } from './tools/delete-api-key.js';
70
+ import { getSubscriptionTool } from './tools/get-subscription.js';
71
+ import { cancelSubscriptionTool } from './tools/cancel-subscription.js';
72
+ import { pauseSubscriptionTool } from './tools/pause-subscription.js';
73
+ import { resumeSubscriptionTool } from './tools/resume-subscription.js';
74
+ import { downgradeSubscriptionTool } from './tools/downgrade-subscription.js';
69
75
  import { listOAuthClientsTool } from './tools/list-oauth-clients.js';
70
76
  import { createOAuthClientTool } from './tools/create-oauth-client.js';
71
77
  import { updateOAuthClientTool } from './tools/update-oauth-client.js';
@@ -184,6 +190,51 @@ server.tool(deleteApiKeyTool.name, deleteApiKeyTool.description, deleteApiKeyToo
184
190
  return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
185
191
  }
186
192
  });
193
+ server.tool(getSubscriptionTool.name, getSubscriptionTool.description, getSubscriptionTool.inputSchema.shape, async () => {
194
+ try {
195
+ const text = await getSubscriptionTool.execute(client);
196
+ return { content: [{ type: 'text', text }] };
197
+ }
198
+ catch (err) {
199
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
200
+ }
201
+ });
202
+ server.tool(cancelSubscriptionTool.name, cancelSubscriptionTool.description, cancelSubscriptionTool.inputSchema.shape, async (input) => {
203
+ try {
204
+ const text = await cancelSubscriptionTool.execute(client, input);
205
+ return { content: [{ type: 'text', text }] };
206
+ }
207
+ catch (err) {
208
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
209
+ }
210
+ });
211
+ server.tool(pauseSubscriptionTool.name, pauseSubscriptionTool.description, pauseSubscriptionTool.inputSchema.shape, async (input) => {
212
+ try {
213
+ const text = await pauseSubscriptionTool.execute(client, input);
214
+ return { content: [{ type: 'text', text }] };
215
+ }
216
+ catch (err) {
217
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
218
+ }
219
+ });
220
+ server.tool(resumeSubscriptionTool.name, resumeSubscriptionTool.description, resumeSubscriptionTool.inputSchema.shape, async () => {
221
+ try {
222
+ const text = await resumeSubscriptionTool.execute(client);
223
+ return { content: [{ type: 'text', text }] };
224
+ }
225
+ catch (err) {
226
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
227
+ }
228
+ });
229
+ server.tool(downgradeSubscriptionTool.name, downgradeSubscriptionTool.description, downgradeSubscriptionTool.inputSchema.shape, async (input) => {
230
+ try {
231
+ const text = await downgradeSubscriptionTool.execute(client, input);
232
+ return { content: [{ type: 'text', text }] };
233
+ }
234
+ catch (err) {
235
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
236
+ }
237
+ });
187
238
  server.tool(listOAuthClientsTool.name, listOAuthClientsTool.description, listOAuthClientsTool.inputSchema.shape, async () => {
188
239
  try {
189
240
  const text = await listOAuthClientsTool.execute(client);
@@ -625,6 +676,15 @@ server.tool(listActivityTool.name, listActivityTool.description, listActivityToo
625
676
  return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
626
677
  }
627
678
  });
679
+ server.tool(getUpdatesTool.name, getUpdatesTool.description, getUpdatesTool.inputSchema.shape, async (input) => {
680
+ try {
681
+ const text = await getUpdatesTool.execute(client, input);
682
+ return { content: [{ type: 'text', text }] };
683
+ }
684
+ catch (err) {
685
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
686
+ }
687
+ });
628
688
  server.tool(listWebhooksTool.name, listWebhooksTool.description, listWebhooksTool.inputSchema.shape, async (input) => {
629
689
  try {
630
690
  const text = await listWebhooksTool.execute(client, input);
@@ -237,7 +237,7 @@ export type AskSupportPayload = {
237
237
  request_human?: boolean;
238
238
  confirm_escalation?: boolean;
239
239
  };
240
- export type ApiKeyScope = 'accounts:read' | 'accounts:write' | 'posts:read' | 'posts:write' | 'media:write' | 'analytics:read';
240
+ export type ApiKeyScope = 'accounts:read' | 'accounts:write' | 'posts:read' | 'posts:write' | 'media:write' | 'analytics:read' | 'billing:read' | 'billing:write';
241
241
  export type CreateApiKeyPayload = {
242
242
  name?: string;
243
243
  scopes?: ApiKeyScope[];
@@ -279,6 +279,43 @@ export type DeleteApiKeyResponse = {
279
279
  is_revoked?: boolean;
280
280
  };
281
281
  };
282
+ export type SubscriptionTierName = 'starter' | 'pro' | 'power_user' | 'agency';
283
+ export type SubscriptionSummary = {
284
+ id: string | null;
285
+ status: string | null;
286
+ tier: string | null;
287
+ cancel_at_period_end: boolean | null;
288
+ current_period_end: string | null;
289
+ trial_ends_at: string | null;
290
+ paused_at: string | null;
291
+ pause_resumes_at: string | null;
292
+ stripe_subscription_id: string | null;
293
+ };
294
+ export type SubscriptionSummaryResponse = {
295
+ subscription: SubscriptionSummary;
296
+ };
297
+ export type CancelSubscriptionPayload = {
298
+ reason: string;
299
+ feedback?: string;
300
+ immediate?: boolean;
301
+ };
302
+ export type CancelSubscriptionResponse = {
303
+ success: true;
304
+ immediate: boolean;
305
+ canceled_at: string | null;
306
+ cancel_at_period_end: boolean;
307
+ };
308
+ export type PauseSubscriptionResponse = {
309
+ success: true;
310
+ pause_resumes_at: string;
311
+ };
312
+ export type ResumeSubscriptionResponse = {
313
+ success: true;
314
+ };
315
+ export type DowngradeSubscriptionResponse = {
316
+ success: true;
317
+ tier: SubscriptionTierName;
318
+ };
282
319
  export type AskSupportResponse = {
283
320
  success: boolean;
284
321
  workspace_id: string;
@@ -502,6 +539,22 @@ export interface ActivityResponse {
502
539
  total: number;
503
540
  limit: number;
504
541
  }
542
+ export interface UpdateEntry {
543
+ slug: string;
544
+ title: string;
545
+ date: string;
546
+ version: string;
547
+ summary: string;
548
+ type: string | null;
549
+ areas: string[];
550
+ url: string;
551
+ image?: string;
552
+ video?: string;
553
+ content?: string;
554
+ }
555
+ export interface UpdatesResponse {
556
+ updates: UpdateEntry[];
557
+ }
505
558
  export interface ApiWebhook {
506
559
  id: string;
507
560
  workspace_id: string | null;
@@ -698,6 +751,13 @@ export declare class PosterlyClient {
698
751
  deleteApiKey(keyId: string, data: {
699
752
  confirm: true;
700
753
  }): Promise<DeleteApiKeyResponse>;
754
+ getSubscription(): Promise<SubscriptionSummaryResponse>;
755
+ cancelSubscription(data: CancelSubscriptionPayload): Promise<CancelSubscriptionResponse>;
756
+ pauseSubscription(): Promise<PauseSubscriptionResponse>;
757
+ resumeSubscription(): Promise<ResumeSubscriptionResponse>;
758
+ downgradeSubscription(data: {
759
+ tier?: SubscriptionTierName;
760
+ }): Promise<DowngradeSubscriptionResponse>;
701
761
  listAccounts(params?: {
702
762
  workspace_id?: string;
703
763
  }): Promise<Account[]>;
@@ -962,6 +1022,11 @@ export declare class PosterlyClient {
962
1022
  type?: 'all' | 'activity' | 'publish';
963
1023
  limit?: number;
964
1024
  }): Promise<ActivityResponse>;
1025
+ getUpdates(params?: {
1026
+ limit?: number;
1027
+ since?: string;
1028
+ include_content?: boolean;
1029
+ }): Promise<UpdatesResponse>;
965
1030
  listWebhooks(params?: {
966
1031
  workspace_id?: string;
967
1032
  }): Promise<{
@@ -122,6 +122,21 @@ export class PosterlyClient {
122
122
  async deleteApiKey(keyId, data) {
123
123
  return this.request('DELETE', `/api-keys/${encodeURIComponent(keyId)}`, data);
124
124
  }
125
+ async getSubscription() {
126
+ return this.request('GET', '/subscription');
127
+ }
128
+ async cancelSubscription(data) {
129
+ return this.request('POST', '/subscription/cancel', data);
130
+ }
131
+ async pauseSubscription() {
132
+ return this.request('POST', '/subscription/pause', {});
133
+ }
134
+ async resumeSubscription() {
135
+ return this.request('POST', '/subscription/resume', {});
136
+ }
137
+ async downgradeSubscription(data) {
138
+ return this.request('POST', '/subscription/downgrade', data);
139
+ }
125
140
  async listAccounts(params) {
126
141
  const searchParams = new URLSearchParams();
127
142
  if (params?.workspace_id)
@@ -401,6 +416,17 @@ export class PosterlyClient {
401
416
  const qs = searchParams.toString();
402
417
  return this.request('GET', `/activity${qs ? `?${qs}` : ''}`);
403
418
  }
419
+ async getUpdates(params) {
420
+ const searchParams = new URLSearchParams();
421
+ if (params?.limit)
422
+ searchParams.set('limit', String(params.limit));
423
+ if (params?.since)
424
+ searchParams.set('since', params.since);
425
+ if (params?.include_content)
426
+ searchParams.set('include_content', 'true');
427
+ const qs = searchParams.toString();
428
+ return this.request('GET', `/updates${qs ? `?${qs}` : ''}`);
429
+ }
404
430
  async listWebhooks(params) {
405
431
  const searchParams = new URLSearchParams();
406
432
  if (params?.workspace_id)
@@ -1 +1 @@
1
- export declare const POSTERLY_MCP_VERSION = "0.24.1";
1
+ export declare const POSTERLY_MCP_VERSION = "0.26.0";
@@ -5,4 +5,4 @@
5
5
  // tool set (minus the intentional pre-auth signup tools that only this stdio
6
6
  // package exposes). `npm run check:mcp-parity` enforces both the version match
7
7
  // and the tool-list match, and runs in the pre-commit hook.
8
- export const POSTERLY_MCP_VERSION = '0.24.1';
8
+ export const POSTERLY_MCP_VERSION = '0.26.0';
@@ -0,0 +1,30 @@
1
+ import { z } from 'zod';
2
+ import type { PosterlyClient } from '../lib/api-client.js';
3
+ declare const CANCELLATION_REASONS: readonly ["too_expensive", "not_using", "missing_features", "technical_issues", "switching_service", "temporary_break", "other"];
4
+ export declare const cancelSubscriptionTool: {
5
+ name: string;
6
+ description: string;
7
+ inputSchema: z.ZodObject<{
8
+ reason: z.ZodEnum<["too_expensive", "not_using", "missing_features", "technical_issues", "switching_service", "temporary_break", "other"]>;
9
+ feedback: z.ZodOptional<z.ZodString>;
10
+ immediate: z.ZodOptional<z.ZodBoolean>;
11
+ confirm: z.ZodLiteral<true>;
12
+ }, "strip", z.ZodTypeAny, {
13
+ confirm: true;
14
+ reason: "too_expensive" | "not_using" | "missing_features" | "technical_issues" | "switching_service" | "temporary_break" | "other";
15
+ feedback?: string | undefined;
16
+ immediate?: boolean | undefined;
17
+ }, {
18
+ confirm: true;
19
+ reason: "too_expensive" | "not_using" | "missing_features" | "technical_issues" | "switching_service" | "temporary_break" | "other";
20
+ feedback?: string | undefined;
21
+ immediate?: boolean | undefined;
22
+ }>;
23
+ execute(client: PosterlyClient, input: {
24
+ reason: (typeof CANCELLATION_REASONS)[number];
25
+ feedback?: string;
26
+ immediate?: boolean;
27
+ confirm: true;
28
+ }): Promise<string>;
29
+ };
30
+ export {};
@@ -0,0 +1,41 @@
1
+ import { z } from 'zod';
2
+ import { mdKeyValue, mdSection, mdTitle } from '../lib/format.js';
3
+ // Mirrors CANCELLATION_REASONS in the main app (lib/subscription-reasons.ts).
4
+ // Kept in sync manually because the npm package cannot import from the app.
5
+ const CANCELLATION_REASONS = [
6
+ 'too_expensive',
7
+ 'not_using',
8
+ 'missing_features',
9
+ 'technical_issues',
10
+ 'switching_service',
11
+ 'temporary_break',
12
+ 'other',
13
+ ];
14
+ function formatCanceled(result) {
15
+ return [
16
+ mdTitle(result.immediate ? 'Subscription cancelled immediately' : 'Subscription set to cancel at period end'),
17
+ mdSection('Details', mdKeyValue([
18
+ ['Immediate', result.immediate ? 'yes' : 'no'],
19
+ ['Cancel at period end', result.cancel_at_period_end ? 'yes' : 'no'],
20
+ ['Canceled at', result.canceled_at || 'at end of current period'],
21
+ ])),
22
+ ].join('\n\n');
23
+ }
24
+ export const cancelSubscriptionTool = {
25
+ name: 'cancel_subscription',
26
+ description: "Cancel the authenticated user's posterly subscription. DESTRUCTIVE billing action; requires the billing:write scope. ALWAYS ask the user why they are cancelling FIRST and pass their answer as `reason` (one of the allowed values). By default the subscription is set to cancel at the end of the current period; pass immediate=true only if the user explicitly wants it cancelled right now. Only call after the user explicitly confirms.",
27
+ inputSchema: z.object({
28
+ reason: z.enum(CANCELLATION_REASONS).describe('Why the user is cancelling. Ask the user before calling; do not guess.'),
29
+ feedback: z.string().max(2000).optional().describe('Optional free-text detail the user gave about why they are cancelling.'),
30
+ immediate: z.boolean().optional().describe('Cancel immediately instead of at period end. Defaults to false (cancel at period end).'),
31
+ confirm: z.literal(true).describe('Must be true after the user explicitly confirms the cancellation.'),
32
+ }),
33
+ async execute(client, input) {
34
+ const result = await client.cancelSubscription({
35
+ reason: input.reason,
36
+ feedback: input.feedback,
37
+ immediate: input.immediate === true,
38
+ });
39
+ return formatCanceled(result);
40
+ },
41
+ };
@@ -5,7 +5,7 @@ export declare const createApiKeyTool: {
5
5
  description: string;
6
6
  inputSchema: z.ZodObject<{
7
7
  name: z.ZodOptional<z.ZodString>;
8
- scopes: z.ZodOptional<z.ZodArray<z.ZodEnum<["accounts:read", "accounts:write", "posts:read", "posts:write", "media:write", "analytics:read"]>, "many">>;
8
+ scopes: z.ZodOptional<z.ZodArray<z.ZodEnum<["accounts:read", "accounts:write", "posts:read", "posts:write", "media:write", "analytics:read", "billing:read", "billing:write"]>, "many">>;
9
9
  workspace_id: z.ZodOptional<z.ZodString>;
10
10
  expires_in_days: z.ZodOptional<z.ZodNumber>;
11
11
  confirm: z.ZodLiteral<true>;
@@ -13,13 +13,13 @@ export declare const createApiKeyTool: {
13
13
  confirm: true;
14
14
  workspace_id?: string | undefined;
15
15
  name?: string | undefined;
16
- scopes?: ("accounts:read" | "accounts:write" | "posts:read" | "posts:write" | "media:write" | "analytics:read")[] | undefined;
16
+ scopes?: ("accounts:read" | "accounts:write" | "posts:read" | "posts:write" | "media:write" | "analytics:read" | "billing:read" | "billing:write")[] | undefined;
17
17
  expires_in_days?: number | undefined;
18
18
  }, {
19
19
  confirm: true;
20
20
  workspace_id?: string | undefined;
21
21
  name?: string | undefined;
22
- scopes?: ("accounts:read" | "accounts:write" | "posts:read" | "posts:write" | "media:write" | "analytics:read")[] | undefined;
22
+ scopes?: ("accounts:read" | "accounts:write" | "posts:read" | "posts:write" | "media:write" | "analytics:read" | "billing:read" | "billing:write")[] | undefined;
23
23
  expires_in_days?: number | undefined;
24
24
  }>;
25
25
  execute(client: PosterlyClient, input: CreateApiKeyPayload): Promise<string>;
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { code, mdKeyValue, mdSection, mdTitle } from '../lib/format.js';
3
- const scopeSchema = z.enum(['accounts:read', 'accounts:write', 'posts:read', 'posts:write', 'media:write', 'analytics:read']);
3
+ const scopeSchema = z.enum(['accounts:read', 'accounts:write', 'posts:read', 'posts:write', 'media:write', 'analytics:read', 'billing:read', 'billing:write']);
4
4
  function formatCreatedApiKey(result) {
5
5
  const key = result.api_key;
6
6
  return [
@@ -23,7 +23,7 @@ export const createApiKeyTool = {
23
23
  description: 'Create a new Posterly API key for the authenticated user. SECRET-CREATING WRITE: only use after explicit user confirmation. The new key can only request scopes already present on the calling dashboard-created API key; OAuth and managed assistant tokens cannot mint keys.',
24
24
  inputSchema: z.object({
25
25
  name: z.string().trim().min(1).max(120).optional().describe('Human-readable key name.'),
26
- scopes: z.array(scopeSchema).min(1).max(6).optional().describe('Scopes for the new key. Omit to copy the calling key scopes. Cannot exceed the calling key scopes.'),
26
+ scopes: z.array(scopeSchema).min(1).max(8).optional().describe('Scopes for the new key. Omit to copy the calling key scopes. Cannot exceed the calling key scopes. billing:read and billing:write allow managing the posterly subscription (cancel/pause/resume/downgrade).'),
27
27
  workspace_id: z.string().trim().min(1).optional().describe('Optional workspace restriction. Workspace-scoped calling keys cannot create keys outside their workspace.'),
28
28
  expires_in_days: z.number().int().min(1).max(365).optional().describe('Optional expiry from now, up to 365 days. Omit for no expiry.'),
29
29
  confirm: z.literal(true).describe('Must be true after the user explicitly confirms that a new secret API key should be created.'),