posterly-mcp-server 0.39.0 → 0.40.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.
package/README.md CHANGED
@@ -122,7 +122,7 @@ Add the same server definition to your Cursor MCP settings:
122
122
 
123
123
  ## Available tools
124
124
 
125
- `posterly-mcp-server@0.39.0` exposes 89 tools.
125
+ `posterly-mcp-server@0.40.0` exposes 89 tools.
126
126
 
127
127
  Public setup tools work before `POSTERLY_API_KEY` exists:
128
128
 
@@ -440,6 +440,12 @@ export interface Workspace {
440
440
  timezone?: string | null;
441
441
  role?: string;
442
442
  }
443
+ export interface WhoamiOnboarding {
444
+ completed: boolean;
445
+ next_step: string;
446
+ next_step_label: string;
447
+ instruction: string;
448
+ }
443
449
  export interface Whoami {
444
450
  user: {
445
451
  id: string;
@@ -451,6 +457,7 @@ export interface Whoami {
451
457
  };
452
458
  default_workspace: Workspace;
453
459
  workspaces: Workspace[];
460
+ onboarding?: WhoamiOnboarding;
454
461
  }
455
462
  export interface AccountAnalyticsSummary {
456
463
  current_followers: number;
@@ -1 +1 @@
1
- export declare const POSTERLY_MCP_VERSION = "0.39.0";
1
+ export declare const POSTERLY_MCP_VERSION = "0.40.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.39.0';
8
+ export const POSTERLY_MCP_VERSION = '0.40.0';
@@ -17,11 +17,12 @@ export const getAgentSignupInfoTool = {
17
17
  '- start_signup: starts paid signup and returns a Posterly checkout handoff URL plus a signup poll URL.',
18
18
  '- get_signup_session: polls checkout, payment, password, and agent-access status.',
19
19
  '',
20
- 'After Posterly access is installed:',
21
- '- whoami: confirm the paid Posterly account/workspace.',
22
- '- create_connect_session: create a secure browser OAuth handoff for the social platform the user chooses.',
23
- '- get_connect_session: poll the OAuth handoff until connected.',
24
- '- create_post: schedule posts after the user confirms the account and content.',
20
+ 'After Posterly access is installed, onboard the user IN THIS chat (do not send them to /onboarding-v2):',
21
+ '- whoami: confirm the paid account and read onboarding.next_step.',
22
+ '- About you: confirm name and IANA timezone.',
23
+ '- create_connect_session / get_connect_session: first social account in the browser.',
24
+ '- Brand voice: ask how they want to sound, then use that on captions.',
25
+ '- create_post: first scheduled post after validate_post and explicit confirm.',
25
26
  '',
26
27
  'Conversation style:',
27
28
  '- Keep the user updated in plain language: checkout pending, payment confirmed, password setup needed, account connected, post scheduled.',
@@ -59,9 +59,9 @@ function guidanceForStatus(status) {
59
59
  case 'authorize_agent':
60
60
  return 'Tell the user Posterly is ready for agent authorization. Send them the provided authorization or completion link if one is present.';
61
61
  case 'agent_access_required':
62
- return 'Tell the user API access is active, but this AI still needs Posterly access. Ask them to paste the Posterly MCP/API setup instructions here or install the Posterly MCP server, then continue with social account connection.';
62
+ return 'Tell the user API access is active, but this AI still needs Posterly access. Ask them to paste the Posterly MCP/API setup instructions here or install the Posterly MCP server. Then onboard them IN THIS chat: about you, connect, brand voice, first post. Do not send them to /onboarding-v2.';
63
63
  case 'api_access_active':
64
- return 'Posterly API access is active. Ask which social account the user wants to connect first, then create a connect session.';
64
+ return 'Posterly API access is active. Call whoami, then onboard them IN THIS chat: about you (name and timezone), connect the first account, brand voice, first post. Do not send them to /onboarding-v2.';
65
65
  default:
66
66
  return 'Explain the current status to the user and keep polling unless the session is terminal.';
67
67
  }
@@ -78,7 +78,7 @@ function formatSignupStart(response, includeRaw) {
78
78
  '1. Send the Checkout handoff URL to the user so they can pay securely in their browser. Use the raw Stripe checkout URL only if you preserve the full URL including any fragment. posterly does not email this link, so do not tell the user to check their inbox at this stage.',
79
79
  '2. Call get_signup_session with the signup session ID until the status changes.',
80
80
  '3. Tell the user when Posterly sends the password setup email.',
81
- '4. If status becomes agent_access_required, ask the user to install or paste the Posterly MCP/API setup instructions into this trusted AI chat.',
81
+ '4. If status becomes agent_access_required, ask the user to install or paste the Posterly MCP/API setup instructions into this trusted AI chat, then onboard them in this conversation (about you, connect, brand voice, first post). Do not send them to /onboarding-v2.',
82
82
  '5. Do not ask for card details, the Posterly password, social passwords, or OAuth codes.',
83
83
  includeRaw ? `\nRaw signup response:\n${JSON.stringify(response, null, 2)}` : '',
84
84
  ];
@@ -2,7 +2,7 @@ import { z } from 'zod';
2
2
  import { code, mdKeyValue, mdTable, mdTitle } from '../lib/format.js';
3
3
  export const whoamiTool = {
4
4
  name: 'whoami',
5
- description: 'Return the authenticated user, API key scopes, the default (personal) workspace, and every workspace the caller can post in. ALWAYS call this at the start of a session before creating, listing, or scheduling posts - posts created without an explicit workspace_id land in the default workspace shown here, and confirming with the user first prevents posts from appearing in the wrong workspace.',
5
+ description: 'Return the authenticated user, API key scopes, workspaces, and onboarding next step. ALWAYS call this at the start of a session. If onboarding.completed is false, walk the remaining onboarding steps IN THIS conversation (about you, connect, brand voice, first post). Do not send the user to /onboarding-v2 or the dashboard composer wizard.',
6
6
  inputSchema: z.object({}),
7
7
  async execute(client) {
8
8
  const info = await client.whoami();
@@ -13,7 +13,11 @@ export const whoamiTool = {
13
13
  ['API scopes', info.api_key.scopes.join(', ') || 'none'],
14
14
  ['Default workspace', `${info.default_workspace.name} (${code(info.default_workspace.id)})`],
15
15
  ['Default timezone', info.default_workspace.timezone || 'n/a'],
16
+ ['Onboarding', info.onboarding?.completed ? 'complete' : info.onboarding?.next_step_label || 'unknown'],
16
17
  ]),
18
+ info.onboarding && !info.onboarding.completed
19
+ ? `**Onboarding next:** ${info.onboarding.next_step_label}. ${info.onboarding.instruction}`
20
+ : '',
17
21
  mdTable(['Workspace', 'Workspace ID', 'Role', 'Timezone', 'Default'], info.workspaces.map((workspace) => [
18
22
  `${workspace.name}${workspace.is_personal ? ' (personal)' : ''}`,
19
23
  code(workspace.id),
@@ -22,6 +26,6 @@ export const whoamiTool = {
22
26
  workspace.id === info.default_workspace.id,
23
27
  ])),
24
28
  '**Tip:** Pass `workspace_id` to `create_post`, `list_posts`, `list_accounts`, and `find_available_slot` when you want the assistant to stay inside one workspace.',
25
- ].join('\n\n');
29
+ ].filter(Boolean).join('\n\n');
26
30
  },
27
31
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "posterly-mcp-server",
3
- "version": "0.39.0",
3
+ "version": "0.40.0",
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.39.0",
6
+ "version": "0.40.0",
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.39.0",
17
+ "version": "0.40.0",
18
18
  "transport": {
19
19
  "type": "stdio"
20
20
  },
@@ -465,11 +465,19 @@ export interface Workspace {
465
465
  role?: string;
466
466
  }
467
467
 
468
+ export interface WhoamiOnboarding {
469
+ completed: boolean;
470
+ next_step: string;
471
+ next_step_label: string;
472
+ instruction: string;
473
+ }
474
+
468
475
  export interface Whoami {
469
476
  user: { id: string; email: string | null };
470
477
  api_key: { id: string; scopes: string[] };
471
478
  default_workspace: Workspace;
472
479
  workspaces: Workspace[];
480
+ onboarding?: WhoamiOnboarding;
473
481
  }
474
482
 
475
483
  export interface AccountAnalyticsSummary {
@@ -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.39.0';
8
+ export const POSTERLY_MCP_VERSION = '0.40.0';
@@ -22,11 +22,12 @@ export const getAgentSignupInfoTool = {
22
22
  '- start_signup: starts paid signup and returns a Posterly checkout handoff URL plus a signup poll URL.',
23
23
  '- get_signup_session: polls checkout, payment, password, and agent-access status.',
24
24
  '',
25
- 'After Posterly access is installed:',
26
- '- whoami: confirm the paid Posterly account/workspace.',
27
- '- create_connect_session: create a secure browser OAuth handoff for the social platform the user chooses.',
28
- '- get_connect_session: poll the OAuth handoff until connected.',
29
- '- create_post: schedule posts after the user confirms the account and content.',
25
+ 'After Posterly access is installed, onboard the user IN THIS chat (do not send them to /onboarding-v2):',
26
+ '- whoami: confirm the paid account and read onboarding.next_step.',
27
+ '- About you: confirm name and IANA timezone.',
28
+ '- create_connect_session / get_connect_session: first social account in the browser.',
29
+ '- Brand voice: ask how they want to sound, then use that on captions.',
30
+ '- create_post: first scheduled post after validate_post and explicit confirm.',
30
31
  '',
31
32
  'Conversation style:',
32
33
  '- Keep the user updated in plain language: checkout pending, payment confirmed, password setup needed, account connected, post scheduled.',
@@ -68,9 +68,9 @@ function guidanceForStatus(status: string): string {
68
68
  case 'authorize_agent':
69
69
  return 'Tell the user Posterly is ready for agent authorization. Send them the provided authorization or completion link if one is present.';
70
70
  case 'agent_access_required':
71
- return 'Tell the user API access is active, but this AI still needs Posterly access. Ask them to paste the Posterly MCP/API setup instructions here or install the Posterly MCP server, then continue with social account connection.';
71
+ return 'Tell the user API access is active, but this AI still needs Posterly access. Ask them to paste the Posterly MCP/API setup instructions here or install the Posterly MCP server. Then onboard them IN THIS chat: about you, connect, brand voice, first post. Do not send them to /onboarding-v2.';
72
72
  case 'api_access_active':
73
- return 'Posterly API access is active. Ask which social account the user wants to connect first, then create a connect session.';
73
+ return 'Posterly API access is active. Call whoami, then onboard them IN THIS chat: about you (name and timezone), connect the first account, brand voice, first post. Do not send them to /onboarding-v2.';
74
74
  default:
75
75
  return 'Explain the current status to the user and keep polling unless the session is terminal.';
76
76
  }
@@ -99,7 +99,7 @@ function formatSignupStart(response: PublicSignupResponse, includeRaw: boolean):
99
99
  '1. Send the Checkout handoff URL to the user so they can pay securely in their browser. Use the raw Stripe checkout URL only if you preserve the full URL including any fragment. posterly does not email this link, so do not tell the user to check their inbox at this stage.',
100
100
  '2. Call get_signup_session with the signup session ID until the status changes.',
101
101
  '3. Tell the user when Posterly sends the password setup email.',
102
- '4. If status becomes agent_access_required, ask the user to install or paste the Posterly MCP/API setup instructions into this trusted AI chat.',
102
+ '4. If status becomes agent_access_required, ask the user to install or paste the Posterly MCP/API setup instructions into this trusted AI chat, then onboard them in this conversation (about you, connect, brand voice, first post). Do not send them to /onboarding-v2.',
103
103
  '5. Do not ask for card details, the Posterly password, social passwords, or OAuth codes.',
104
104
  includeRaw ? `\nRaw signup response:\n${JSON.stringify(response, null, 2)}` : '',
105
105
  ];
@@ -5,7 +5,7 @@ import { code, mdKeyValue, mdTable, mdTitle } from '../lib/format.js';
5
5
  export const whoamiTool = {
6
6
  name: 'whoami',
7
7
  description:
8
- 'Return the authenticated user, API key scopes, the default (personal) workspace, and every workspace the caller can post in. ALWAYS call this at the start of a session before creating, listing, or scheduling posts - posts created without an explicit workspace_id land in the default workspace shown here, and confirming with the user first prevents posts from appearing in the wrong workspace.',
8
+ 'Return the authenticated user, API key scopes, workspaces, and onboarding next step. ALWAYS call this at the start of a session. If onboarding.completed is false, walk the remaining onboarding steps IN THIS conversation (about you, connect, brand voice, first post). Do not send the user to /onboarding-v2 or the dashboard composer wizard.',
9
9
  inputSchema: z.object({}),
10
10
 
11
11
  async execute(client: PosterlyClient) {
@@ -18,7 +18,11 @@ export const whoamiTool = {
18
18
  ['API scopes', info.api_key.scopes.join(', ') || 'none'],
19
19
  ['Default workspace', `${info.default_workspace.name} (${code(info.default_workspace.id)})`],
20
20
  ['Default timezone', info.default_workspace.timezone || 'n/a'],
21
+ ['Onboarding', info.onboarding?.completed ? 'complete' : info.onboarding?.next_step_label || 'unknown'],
21
22
  ]),
23
+ info.onboarding && !info.onboarding.completed
24
+ ? `**Onboarding next:** ${info.onboarding.next_step_label}. ${info.onboarding.instruction}`
25
+ : '',
22
26
  mdTable(
23
27
  ['Workspace', 'Workspace ID', 'Role', 'Timezone', 'Default'],
24
28
  info.workspaces.map((workspace) => [
@@ -30,6 +34,6 @@ export const whoamiTool = {
30
34
  ]),
31
35
  ),
32
36
  '**Tip:** Pass `workspace_id` to `create_post`, `list_posts`, `list_accounts`, and `find_available_slot` when you want the assistant to stay inside one workspace.',
33
- ].join('\n\n');
37
+ ].filter(Boolean).join('\n\n');
34
38
  },
35
39
  };