posterly-mcp-server 0.3.0 → 0.3.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/dist/index.js CHANGED
@@ -13,7 +13,7 @@ import { deletePostTool } from './tools/delete-post.js';
13
13
  import { whoamiTool } from './tools/whoami.js';
14
14
  const server = new McpServer({
15
15
  name: 'posterly',
16
- version: '0.3.0',
16
+ version: '0.3.1',
17
17
  });
18
18
  let client;
19
19
  try {
@@ -1,7 +1,13 @@
1
1
  import { z } from 'zod';
2
2
  export const createPostTool = {
3
3
  name: 'create_post',
4
- description: 'Schedule or immediately publish a social media post. Provide either account_id OR username+platform to identify the account. If scheduled_at is omitted, the post publishes immediately. IMPORTANT: posts belong to a workspace. If workspace_id is omitted, the server resolves one from the social account, falling back to the caller\'s default (personal) workspace. Call `whoami` first in any new session to confirm which workspace posts will land in, and pass workspace_id explicitly if the user has more than one workspace.',
4
+ description: 'Schedule or immediately publish a social media post. This is a DESTRUCTIVE WRITE that creates content on the user\'s real social accounts once scheduled_at passes, it will be posted publicly and cannot be un-posted.\n\n' +
5
+ 'REQUIRED BEFORE CALLING:\n' +
6
+ '1. Call `whoami` at the start of any new session to confirm which workspace and user you are acting for.\n' +
7
+ '2. Show the user a preview containing ALL of: account(s) and platform(s), final caption text, scheduled time (in the user\'s timezone), media attached (if any), and workspace name.\n' +
8
+ '3. Get explicit confirmation from the user (e.g. "post it", "yes schedule that", "looks good") BEFORE calling this tool. Do NOT infer consent from earlier instructions like "post about X every Monday" — confirm each individual post or the entire batch.\n' +
9
+ '4. If scheduling multiple posts in one turn, list every post first and confirm the batch as a whole before calling create_post repeatedly.\n\n' +
10
+ 'Provide either account_id OR username+platform to identify the account. If scheduled_at is omitted, the post publishes immediately. If workspace_id is omitted, the server resolves one from the social account, falling back to the caller\'s default (personal) workspace — pass workspace_id explicitly if the user has more than one workspace.',
5
11
  inputSchema: z.object({
6
12
  account_id: z.string().optional().describe('Social account ID (from list_accounts)'),
7
13
  username: z.string().optional().describe('Account username (alternative to account_id)'),
@@ -1,7 +1,8 @@
1
1
  import { z } from 'zod';
2
2
  export const deletePostTool = {
3
3
  name: 'delete_post',
4
- description: 'Delete a scheduled or draft post. Cannot delete published or currently publishing posts.',
4
+ description: 'Delete a scheduled or draft post. DESTRUCTIVE and IRREVERSIBLE — the post and its caption cannot be recovered. Cannot delete published or currently publishing posts.\n\n' +
5
+ 'REQUIRED BEFORE CALLING: Fetch the post with `get_post` first and show the user what will be deleted (caption, account, scheduled time). Get explicit confirmation ("yes delete it", "remove it") before calling. Never delete multiple posts in a single batch without listing each one and confirming the full list.',
5
6
  inputSchema: z.object({
6
7
  post_id: z.number().describe('The post ID to delete'),
7
8
  }),
@@ -1,7 +1,8 @@
1
1
  import { z } from 'zod';
2
2
  export const updatePostTool = {
3
3
  name: 'update_post',
4
- description: 'Update a scheduled or draft post. Can change caption, scheduled time, media, or post type. Cannot edit published or currently publishing posts.',
4
+ description: 'Update a scheduled or draft post. DESTRUCTIVE WRITE overwrites the existing post\'s caption/media/schedule. Cannot edit published or currently publishing posts.\n\n' +
5
+ 'REQUIRED BEFORE CALLING: Show the user a side-by-side of the CURRENT post (caption, scheduled time, media) and the PROPOSED changes, and get explicit confirmation ("yes update it", "apply those changes") before calling. Do not auto-edit posts based on a general instruction — each edit needs its own confirmation.',
5
6
  inputSchema: z.object({
6
7
  post_id: z.number().describe('The post ID to update'),
7
8
  caption: z.string().optional().describe('New caption/text content'),
@@ -1,7 +1,9 @@
1
1
  import { z } from 'zod';
2
2
  export const uploadMediaTool = {
3
3
  name: 'upload_media',
4
- description: 'Upload an image or video file to posterly. Returns a URL that can be used with create_post. Supports JPEG, PNG, GIF, WebP, MP4, MOV, WebM. Images up to 10MB, videos up to 50MB. IMPORTANT: If the user shares an image in the chat, use base64_data (not file_path) since chat-uploaded images are not on the local filesystem. Only use file_path when the user provides an actual local filesystem path.',
4
+ description: 'Upload an image or video file to posterly storage. Returns a URL that can be used with create_post. Supports JPEG, PNG, GIF, WebP, MP4, MOV, WebM. Images up to 10MB, videos up to 50MB.\n\n' +
5
+ 'This writes to the user\'s media storage (counts against quota) but does NOT publish the file anywhere. Uploading is safe — it\'s the subsequent `create_post` call that publishes content, and that tool has its own confirmation requirements.\n\n' +
6
+ 'IMPORTANT: If the user shares an image in the chat, use base64_data (not file_path) since chat-uploaded images are not on the local filesystem. Only use file_path when the user provides an actual local filesystem path — never guess paths.',
5
7
  inputSchema: z.object({
6
8
  file_path: z
7
9
  .string()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "posterly-mcp-server",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "MCP server for posterly — schedule social media posts from Claude Desktop",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/index.ts CHANGED
@@ -15,7 +15,7 @@ import { whoamiTool } from './tools/whoami.js';
15
15
 
16
16
  const server = new McpServer({
17
17
  name: 'posterly',
18
- version: '0.3.0',
18
+ version: '0.3.1',
19
19
  });
20
20
 
21
21
  let client: PosterlyClient;
@@ -4,7 +4,13 @@ import type { PosterlyClient } from '../lib/api-client.js';
4
4
  export const createPostTool = {
5
5
  name: 'create_post',
6
6
  description:
7
- 'Schedule or immediately publish a social media post. Provide either account_id OR username+platform to identify the account. If scheduled_at is omitted, the post publishes immediately. IMPORTANT: posts belong to a workspace. If workspace_id is omitted, the server resolves one from the social account, falling back to the caller\'s default (personal) workspace. Call `whoami` first in any new session to confirm which workspace posts will land in, and pass workspace_id explicitly if the user has more than one workspace.',
7
+ 'Schedule or immediately publish a social media post. This is a DESTRUCTIVE WRITE that creates content on the user\'s real social accounts once scheduled_at passes, it will be posted publicly and cannot be un-posted.\n\n' +
8
+ 'REQUIRED BEFORE CALLING:\n' +
9
+ '1. Call `whoami` at the start of any new session to confirm which workspace and user you are acting for.\n' +
10
+ '2. Show the user a preview containing ALL of: account(s) and platform(s), final caption text, scheduled time (in the user\'s timezone), media attached (if any), and workspace name.\n' +
11
+ '3. Get explicit confirmation from the user (e.g. "post it", "yes schedule that", "looks good") BEFORE calling this tool. Do NOT infer consent from earlier instructions like "post about X every Monday" — confirm each individual post or the entire batch.\n' +
12
+ '4. If scheduling multiple posts in one turn, list every post first and confirm the batch as a whole before calling create_post repeatedly.\n\n' +
13
+ 'Provide either account_id OR username+platform to identify the account. If scheduled_at is omitted, the post publishes immediately. If workspace_id is omitted, the server resolves one from the social account, falling back to the caller\'s default (personal) workspace — pass workspace_id explicitly if the user has more than one workspace.',
8
14
  inputSchema: z.object({
9
15
  account_id: z.string().optional().describe('Social account ID (from list_accounts)'),
10
16
  username: z.string().optional().describe('Account username (alternative to account_id)'),
@@ -4,7 +4,8 @@ import type { PosterlyClient } from '../lib/api-client.js';
4
4
  export const deletePostTool = {
5
5
  name: 'delete_post',
6
6
  description:
7
- 'Delete a scheduled or draft post. Cannot delete published or currently publishing posts.',
7
+ 'Delete a scheduled or draft post. DESTRUCTIVE and IRREVERSIBLE — the post and its caption cannot be recovered. Cannot delete published or currently publishing posts.\n\n' +
8
+ 'REQUIRED BEFORE CALLING: Fetch the post with `get_post` first and show the user what will be deleted (caption, account, scheduled time). Get explicit confirmation ("yes delete it", "remove it") before calling. Never delete multiple posts in a single batch without listing each one and confirming the full list.',
8
9
  inputSchema: z.object({
9
10
  post_id: z.number().describe('The post ID to delete'),
10
11
  }),
@@ -4,7 +4,8 @@ import type { PosterlyClient } from '../lib/api-client.js';
4
4
  export const updatePostTool = {
5
5
  name: 'update_post',
6
6
  description:
7
- 'Update a scheduled or draft post. Can change caption, scheduled time, media, or post type. Cannot edit published or currently publishing posts.',
7
+ 'Update a scheduled or draft post. DESTRUCTIVE WRITE overwrites the existing post\'s caption/media/schedule. Cannot edit published or currently publishing posts.\n\n' +
8
+ 'REQUIRED BEFORE CALLING: Show the user a side-by-side of the CURRENT post (caption, scheduled time, media) and the PROPOSED changes, and get explicit confirmation ("yes update it", "apply those changes") before calling. Do not auto-edit posts based on a general instruction — each edit needs its own confirmation.',
8
9
  inputSchema: z.object({
9
10
  post_id: z.number().describe('The post ID to update'),
10
11
  caption: z.string().optional().describe('New caption/text content'),
@@ -4,7 +4,9 @@ import type { PosterlyClient } from '../lib/api-client.js';
4
4
  export const uploadMediaTool = {
5
5
  name: 'upload_media',
6
6
  description:
7
- 'Upload an image or video file to posterly. Returns a URL that can be used with create_post. Supports JPEG, PNG, GIF, WebP, MP4, MOV, WebM. Images up to 10MB, videos up to 50MB. IMPORTANT: If the user shares an image in the chat, use base64_data (not file_path) since chat-uploaded images are not on the local filesystem. Only use file_path when the user provides an actual local filesystem path.',
7
+ 'Upload an image or video file to posterly storage. Returns a URL that can be used with create_post. Supports JPEG, PNG, GIF, WebP, MP4, MOV, WebM. Images up to 10MB, videos up to 50MB.\n\n' +
8
+ 'This writes to the user\'s media storage (counts against quota) but does NOT publish the file anywhere. Uploading is safe — it\'s the subsequent `create_post` call that publishes content, and that tool has its own confirmation requirements.\n\n' +
9
+ 'IMPORTANT: If the user shares an image in the chat, use base64_data (not file_path) since chat-uploaded images are not on the local filesystem. Only use file_path when the user provides an actual local filesystem path — never guess paths.',
8
10
  inputSchema: z.object({
9
11
  file_path: z
10
12
  .string()