posterly-mcp-server 0.47.1 → 0.48.1

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
@@ -123,7 +123,7 @@ Add the same server definition to your Cursor MCP settings:
123
123
 
124
124
  ## Available tools
125
125
 
126
- `posterly-mcp-server@0.47.1` exposes 62 tools covering 95 actions. The hosted HTTP endpoint exposes the same catalog minus the three signup tools: 59 tools covering 92 actions.
126
+ `posterly-mcp-server@0.48.1` exposes 62 tools covering 95 actions. The hosted HTTP endpoint exposes the same catalog minus the three signup tools: 59 tools covering 92 actions.
127
127
 
128
128
  Many tools pick what to do with one parameter: `view` (reads), `action` (writes), or `type`. A few pick their mode from which parameters you pass (for example `update_post` with `status` changes the status instead of editing). Every tool description names all of its views and actions.
129
129
 
@@ -217,7 +217,7 @@ Accounts, posting, media, schedule, analytics, and support. What most assistants
217
217
 
218
218
  | Mode (picked by params) | What it does |
219
219
  | --- | --- |
220
- | `post` (default) | Delete one post. Published Instagram or Facebook posts also need `confirm_published` |
220
+ | `post` (default) | Delete one post. Choose `delete_mode`: `posterly` keeps live content; `platform` also requires `confirm_published` |
221
221
  | `group` (pass `group_id`) | Delete a post group (preview then confirm). Never deletes published posts |
222
222
 
223
223
  **`upload_media`**: Upload media
@@ -1265,6 +1265,7 @@ export declare class PosterlyClient {
1265
1265
  }>;
1266
1266
  deletePost(id: number, options?: {
1267
1267
  confirmPublished?: boolean;
1268
+ deleteMode?: 'posterly' | 'platform';
1268
1269
  }): Promise<{
1269
1270
  deleted: boolean;
1270
1271
  id: number;
@@ -378,7 +378,12 @@ export class PosterlyClient {
378
378
  return this.request('PATCH', `/posts/${id}`, data);
379
379
  }
380
380
  async deletePost(id, options) {
381
- const qs = options?.confirmPublished ? '?confirm_published=true' : '';
381
+ const params = new URLSearchParams();
382
+ if (options?.confirmPublished)
383
+ params.set('confirm_published', 'true');
384
+ if (options?.deleteMode)
385
+ params.set('delete_mode', options.deleteMode);
386
+ const qs = params.size ? `?${params}` : '';
382
387
  return this.request('DELETE', `/posts/${id}${qs}`);
383
388
  }
384
389
  async setPostApproval(id, data) {
@@ -1 +1 @@
1
- export declare const POSTERLY_MCP_VERSION = "0.47.1";
1
+ export declare const POSTERLY_MCP_VERSION = "0.48.1";
@@ -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.47.1';
8
+ export const POSTERLY_MCP_VERSION = '0.48.1';
@@ -4,6 +4,7 @@ import { type ToolContext } from '../lib/tool-runtime.js';
4
4
  type DeletePostInput = {
5
5
  post_id?: number;
6
6
  group_id?: string;
7
+ delete_mode?: 'posterly' | 'platform';
7
8
  confirm_published?: boolean;
8
9
  confirm?: boolean;
9
10
  preview_id?: string;
@@ -14,6 +15,7 @@ export declare const deletePostTool: {
14
15
  inputSchema: z.ZodObject<{
15
16
  post_id: z.ZodOptional<z.ZodNumber>;
16
17
  group_id: z.ZodOptional<z.ZodString>;
18
+ delete_mode: z.ZodOptional<z.ZodEnum<["posterly", "platform"]>>;
17
19
  confirm_published: z.ZodOptional<z.ZodBoolean>;
18
20
  confirm: z.ZodOptional<z.ZodBoolean>;
19
21
  preview_id: z.ZodOptional<z.ZodString>;
@@ -21,14 +23,16 @@ export declare const deletePostTool: {
21
23
  confirm?: boolean | undefined;
22
24
  preview_id?: string | undefined;
23
25
  post_id?: number | undefined;
24
- group_id?: string | undefined;
25
26
  confirm_published?: boolean | undefined;
27
+ delete_mode?: "platform" | "posterly" | undefined;
28
+ group_id?: string | undefined;
26
29
  }, {
27
30
  confirm?: boolean | undefined;
28
31
  preview_id?: string | undefined;
29
32
  post_id?: number | undefined;
30
- group_id?: string | undefined;
31
33
  confirm_published?: boolean | undefined;
34
+ delete_mode?: "platform" | "posterly" | undefined;
35
+ group_id?: string | undefined;
32
36
  }>;
33
37
  /** The old tools' exact input schemas, for alias calls (see alias-transport.ts). */
34
38
  legacySchemas: {
@@ -3,14 +3,15 @@ import { code, dashboardUrlForPosts } from '../lib/format.js';
3
3
  import { previewThenConfirm, validateArgs } from '../lib/tool-runtime.js';
4
4
  export const deletePostTool = {
5
5
  name: 'delete_post',
6
- description: 'Delete posts. DESTRUCTIVE and IRREVERSIBLE: deleted posts and captions cannot be recovered. post_id: delete one post; fetch it with `get_post` first, show the user what will be deleted (caption, account, scheduled time), and pass confirm=true only after explicit confirmation ("yes delete it", "remove it"). A post that is currently publishing is never deleted. A published post is taken down only when the user also explicitly confirms the live removal and you pass confirm_published=true. Instagram and Facebook are attempted when the stored id and token allow it. Every other platform, or a live URL with no id, returns platform_delete_unsupported and the posterly row is kept. A published post with no live URL and no platform id is removed from posterly only. group_id: delete every draft, scheduled, failed, or paused post matching a caller-defined group_id, post_group_id, api_group_id, or release_id. A group delete never removes published posts. Preview then confirm: call without confirm to get a preview and preview_id, show it, then call again with confirm=true and that preview_id. Never delete several posts one by one without listing each and confirming the full list.',
6
+ description: 'Delete posts. DESTRUCTIVE and IRREVERSIBLE: deleted posts and captions cannot be recovered. post_id: delete one post; fetch it with `get_post` first, show the user what will be deleted (caption, account, scheduled time), and pass confirm=true only after explicit confirmation ("yes delete it", "remove it"). A post that is currently publishing is never deleted. A published post is taken down only when the user also explicitly confirms the live removal and you pass confirm_published=true. Choose delete_mode=posterly to remove only the posterly record and leave the live post up, or delete_mode=platform with confirm_published=true to take down the live post too. Live deletion supports eligible connected platforms with saved post IDs and deletion permissions; refusals keep the record. Threads requires threads_delete. YouTube requires youtube.force-ssl or equivalent, upload alone is insufficient. A published post with no live URL and no platform id is removed from posterly only. group_id: delete every draft, scheduled, failed, or paused post matching a caller-defined group_id, post_group_id, api_group_id, or release_id. A group delete never removes published posts. Preview then confirm: call without confirm to get a preview and preview_id, show it, then call again with confirm=true and that preview_id. Never delete several posts one by one without listing each and confirming the full list.',
7
7
  inputSchema: z.object({
8
8
  post_id: z.number().optional().describe('Delete this one post.'),
9
9
  group_id: z.string().min(1).max(160).optional().describe('Delete every unpublished post in this group or release instead. Never deletes published posts.'),
10
+ delete_mode: z.enum(['posterly', 'platform']).optional().describe('posterly removes only the record; platform also takes down live content and requires confirm_published=true.'),
10
11
  confirm_published: z
11
12
  .boolean()
12
13
  .optional()
13
- .describe('With post_id only. True only after the user explicitly confirms taking a live Instagram or Facebook post down. Without it, a published post is refused and kept.'),
14
+ .describe('With post_id only. True only after the user explicitly confirms taking a live post down. Required with delete_mode=platform. Use delete_mode=posterly to leave the live post up.'),
14
15
  confirm: z
15
16
  .boolean()
16
17
  .optional()
@@ -53,13 +54,16 @@ async function deleteOne(client, input) {
53
54
  if (input.confirm !== true) {
54
55
  throw new Error('Refusing to delete post without confirm=true after explicit user confirmation.');
55
56
  }
56
- const result = await client.deletePost(input.post_id, { confirmPublished: input.confirm_published === true });
57
- const platformDelete = result.platform_delete ? ` Platform delete: ${result.platform_delete}.` : '';
57
+ const result = await client.deletePost(input.post_id, { confirmPublished: input.confirm_published === true, deleteMode: input.delete_mode });
58
+ const platformDelete = result.platform_delete === 'deleted' ? ' The platform confirmed removal of the live content.'
59
+ : result.platform_delete === 'not_requested' ? ' Only the posterly record was removed; no platform deletion was requested.'
60
+ : result.platform_delete === 'no_live_target' ? ' Only the posterly record was removed because no live target was saved.'
61
+ : '';
58
62
  return [
59
63
  `Post #${result.id} deleted successfully.${platformDelete}`,
60
64
  'It has been removed from the posterly queue.',
61
65
  `View queue in posterly: ${dashboardUrlForPosts()}`,
62
66
  '',
63
- 'Next step for the AI agent: tell the user the post is gone and offer to create, reschedule, or review the next post.',
67
+ 'Tell the user whether the live post was deleted or kept on the platform.',
64
68
  ].join('\n');
65
69
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "posterly-mcp-server",
3
- "version": "0.47.1",
3
+ "version": "0.48.1",
4
4
  "mcpName": "io.github.awpthorp/posterly",
5
5
  "description": "MCP server for posterly: schedule and publish social media posts across 18 platforms from any MCP client (Claude, ChatGPT, Cursor, Windsurf, Cline, and more)",
6
6
  "license": "MIT",
package/server.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "name": "io.github.awpthorp/posterly",
4
4
  "title": "posterly",
5
5
  "description": "Validate, schedule, publish, and analyze social content across 18 platforms with posterly.",
6
- "version": "0.47.1",
6
+ "version": "0.48.1",
7
7
  "websiteUrl": "https://www.poster.ly/mcp",
8
8
  "repository": {
9
9
  "url": "https://github.com/awpthorp/posterly",
@@ -14,7 +14,7 @@
14
14
  {
15
15
  "registryType": "npm",
16
16
  "identifier": "posterly-mcp-server",
17
- "version": "0.47.1",
17
+ "version": "0.48.1",
18
18
  "transport": {
19
19
  "type": "stdio"
20
20
  },
@@ -1636,9 +1636,12 @@ export class PosterlyClient {
1636
1636
 
1637
1637
  async deletePost(
1638
1638
  id: number,
1639
- options?: { confirmPublished?: boolean },
1639
+ options?: { confirmPublished?: boolean; deleteMode?: 'posterly' | 'platform' },
1640
1640
  ): Promise<{ deleted: boolean; id: number; platform_delete?: string }> {
1641
- const qs = options?.confirmPublished ? '?confirm_published=true' : '';
1641
+ const params = new URLSearchParams();
1642
+ if (options?.confirmPublished) params.set('confirm_published', 'true');
1643
+ if (options?.deleteMode) params.set('delete_mode', options.deleteMode);
1644
+ const qs = params.size ? `?${params}` : '';
1642
1645
  return this.request('DELETE', `/posts/${id}${qs}`);
1643
1646
  }
1644
1647
 
@@ -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.47.1';
8
+ export const POSTERLY_MCP_VERSION = '0.48.1';
@@ -6,6 +6,7 @@ import { previewThenConfirm, validateArgs, type ToolContext } from '../lib/tool-
6
6
  type DeletePostInput = {
7
7
  post_id?: number;
8
8
  group_id?: string;
9
+ delete_mode?: 'posterly' | 'platform';
9
10
  confirm_published?: boolean;
10
11
  confirm?: boolean;
11
12
  preview_id?: string;
@@ -14,14 +15,15 @@ type DeletePostInput = {
14
15
  export const deletePostTool = {
15
16
  name: 'delete_post',
16
17
  description:
17
- 'Delete posts. DESTRUCTIVE and IRREVERSIBLE: deleted posts and captions cannot be recovered. post_id: delete one post; fetch it with `get_post` first, show the user what will be deleted (caption, account, scheduled time), and pass confirm=true only after explicit confirmation ("yes delete it", "remove it"). A post that is currently publishing is never deleted. A published post is taken down only when the user also explicitly confirms the live removal and you pass confirm_published=true. Instagram and Facebook are attempted when the stored id and token allow it. Every other platform, or a live URL with no id, returns platform_delete_unsupported and the posterly row is kept. A published post with no live URL and no platform id is removed from posterly only. group_id: delete every draft, scheduled, failed, or paused post matching a caller-defined group_id, post_group_id, api_group_id, or release_id. A group delete never removes published posts. Preview then confirm: call without confirm to get a preview and preview_id, show it, then call again with confirm=true and that preview_id. Never delete several posts one by one without listing each and confirming the full list.',
18
+ 'Delete posts. DESTRUCTIVE and IRREVERSIBLE: deleted posts and captions cannot be recovered. post_id: delete one post; fetch it with `get_post` first, show the user what will be deleted (caption, account, scheduled time), and pass confirm=true only after explicit confirmation ("yes delete it", "remove it"). A post that is currently publishing is never deleted. A published post is taken down only when the user also explicitly confirms the live removal and you pass confirm_published=true. Choose delete_mode=posterly to remove only the posterly record and leave the live post up, or delete_mode=platform with confirm_published=true to take down the live post too. Live deletion supports eligible connected platforms with saved post IDs and deletion permissions; refusals keep the record. Threads requires threads_delete. YouTube requires youtube.force-ssl or equivalent, upload alone is insufficient. A published post with no live URL and no platform id is removed from posterly only. group_id: delete every draft, scheduled, failed, or paused post matching a caller-defined group_id, post_group_id, api_group_id, or release_id. A group delete never removes published posts. Preview then confirm: call without confirm to get a preview and preview_id, show it, then call again with confirm=true and that preview_id. Never delete several posts one by one without listing each and confirming the full list.',
18
19
  inputSchema: z.object({
19
20
  post_id: z.number().optional().describe('Delete this one post.'),
20
21
  group_id: z.string().min(1).max(160).optional().describe('Delete every unpublished post in this group or release instead. Never deletes published posts.'),
22
+ delete_mode: z.enum(['posterly', 'platform']).optional().describe('posterly removes only the record; platform also takes down live content and requires confirm_published=true.'),
21
23
  confirm_published: z
22
24
  .boolean()
23
25
  .optional()
24
- .describe('With post_id only. True only after the user explicitly confirms taking a live Instagram or Facebook post down. Without it, a published post is refused and kept.'),
26
+ .describe('With post_id only. True only after the user explicitly confirms taking a live post down. Required with delete_mode=platform. Use delete_mode=posterly to leave the live post up.'),
25
27
  confirm: z
26
28
  .boolean()
27
29
  .optional()
@@ -58,24 +60,27 @@ export const deletePostTool = {
58
60
  },
59
61
  });
60
62
  }
61
- return deleteOne(client, args as { post_id: number; confirm?: boolean; confirm_published?: boolean });
63
+ return deleteOne(client, args as { post_id: number; confirm?: boolean; confirm_published?: boolean; delete_mode?: 'posterly' | 'platform' });
62
64
  },
63
65
  };
64
66
 
65
67
  async function deleteOne(
66
68
  client: PosterlyClient,
67
- input: { post_id: number; confirm?: boolean; confirm_published?: boolean },
69
+ input: { post_id: number; confirm?: boolean; confirm_published?: boolean; delete_mode?: 'posterly' | 'platform' },
68
70
  ): Promise<string> {
69
71
  if (input.confirm !== true) {
70
72
  throw new Error('Refusing to delete post without confirm=true after explicit user confirmation.');
71
73
  }
72
- const result = await client.deletePost(input.post_id, { confirmPublished: input.confirm_published === true });
73
- const platformDelete = result.platform_delete ? ` Platform delete: ${result.platform_delete}.` : '';
74
+ const result = await client.deletePost(input.post_id, { confirmPublished: input.confirm_published === true, deleteMode: input.delete_mode });
75
+ const platformDelete = result.platform_delete === 'deleted' ? ' The platform confirmed removal of the live content.'
76
+ : result.platform_delete === 'not_requested' ? ' Only the posterly record was removed; no platform deletion was requested.'
77
+ : result.platform_delete === 'no_live_target' ? ' Only the posterly record was removed because no live target was saved.'
78
+ : '';
74
79
  return [
75
80
  `Post #${result.id} deleted successfully.${platformDelete}`,
76
81
  'It has been removed from the posterly queue.',
77
82
  `View queue in posterly: ${dashboardUrlForPosts()}`,
78
83
  '',
79
- 'Next step for the AI agent: tell the user the post is gone and offer to create, reschedule, or review the next post.',
84
+ 'Tell the user whether the live post was deleted or kept on the platform.',
80
85
  ].join('\n');
81
86
  }
@@ -161,6 +161,7 @@
161
161
  "cancel_subscription",
162
162
  "pause_subscription",
163
163
  "resume_subscription",
164
- "downgrade_subscription"
164
+ "downgrade_subscription",
165
+ "delete_post"
165
166
  ]
166
167
  }
@@ -781,7 +781,7 @@
781
781
  "label": "Delete posts",
782
782
  "exception": {
783
783
  "category": "publishing",
784
- "reason": "Removes scheduled content before it goes out to a social network."
784
+ "reason": "Removes a post record or live platform content after explicit confirmation."
785
785
  },
786
786
  "selector": "params",
787
787
  "defaultMode": "post",
@@ -790,7 +790,7 @@
790
790
  "label": "Delete one post",
791
791
  "destructive": true,
792
792
  "idempotent": true,
793
- "openWorld": false,
793
+ "openWorld": true,
794
794
  "confirm": "confirm",
795
795
  "params": {
796
796
  "post_id": {
@@ -800,6 +800,13 @@
800
800
  },
801
801
  "confirm_published": {
802
802
  "type": "boolean"
803
+ },
804
+ "delete_mode": {
805
+ "type": "string",
806
+ "enum": [
807
+ "posterly",
808
+ "platform"
809
+ ]
803
810
  }
804
811
  }
805
812
  },