posterly-mcp-server 0.43.1 → 0.43.3
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 +2 -2
- package/dist/lib/api-client.d.ts +49 -0
- package/dist/lib/version.d.ts +1 -1
- package/dist/lib/version.js +1 -1
- package/dist/tools/create-webhook.d.ts +2 -2
- package/dist/tools/get-agent-signup-info.js +6 -3
- package/dist/tools/get-signup-session.js +23 -4
- package/dist/tools/start-signup.d.ts +4 -0
- package/dist/tools/start-signup.js +48 -7
- package/dist/tools/update-webhook.d.ts +2 -2
- package/package.json +1 -1
- package/server.json +2 -2
- package/src/lib/api-client.ts +62 -0
- package/src/lib/version.ts +1 -1
- package/src/tools/get-agent-signup-info.ts +6 -3
- package/src/tools/get-signup-session.ts +27 -4
- package/src/tools/start-signup.ts +49 -7
package/README.md
CHANGED
|
@@ -122,13 +122,13 @@ Add the same server definition to your Cursor MCP settings:
|
|
|
122
122
|
|
|
123
123
|
## Available tools
|
|
124
124
|
|
|
125
|
-
`posterly-mcp-server@0.43.
|
|
125
|
+
`posterly-mcp-server@0.43.3` exposes 90 tools.
|
|
126
126
|
|
|
127
127
|
Public setup tools work before `POSTERLY_API_KEY` exists:
|
|
128
128
|
|
|
129
129
|
- `get_mcp_status` (show the installed server version, latest npm version, MCP endpoint health, API auth health, and update guidance)
|
|
130
130
|
- `get_agent_signup_info`
|
|
131
|
-
- `start_signup` (start paid signup and return a
|
|
131
|
+
- `start_signup` (start paid signup and return a poll URL, browser Checkout fallback, and prepaid PaymentIntent fields when agent-card pay is enabled)
|
|
132
132
|
- `get_signup_session` (poll checkout, payment, password, and agent-access status)
|
|
133
133
|
|
|
134
134
|
Authenticated tools require `POSTERLY_API_KEY`:
|
package/dist/lib/api-client.d.ts
CHANGED
|
@@ -821,6 +821,51 @@ export interface PublicSignupPayload {
|
|
|
821
821
|
api_addon?: boolean;
|
|
822
822
|
return_path?: string;
|
|
823
823
|
source?: string;
|
|
824
|
+
tos_accepted?: boolean;
|
|
825
|
+
}
|
|
826
|
+
export interface PublicSignupAgentPay {
|
|
827
|
+
enabled?: boolean;
|
|
828
|
+
method?: string;
|
|
829
|
+
credential_type?: string;
|
|
830
|
+
amount?: number;
|
|
831
|
+
currency?: string;
|
|
832
|
+
amount_display?: string;
|
|
833
|
+
payment_intent_id?: string;
|
|
834
|
+
client_secret?: string | null;
|
|
835
|
+
publishable_key?: string | null;
|
|
836
|
+
confirm_url?: string;
|
|
837
|
+
poll_url?: string;
|
|
838
|
+
checkout_redirect_url?: string;
|
|
839
|
+
pay_instructions?: string;
|
|
840
|
+
status?: string;
|
|
841
|
+
period?: Record<string, unknown>;
|
|
842
|
+
requires_tos_acceptance?: boolean;
|
|
843
|
+
[key: string]: unknown;
|
|
844
|
+
}
|
|
845
|
+
export interface PublicSignupPaymentAgentWalletSpendRequest {
|
|
846
|
+
merchant_name?: string;
|
|
847
|
+
merchant_url?: string;
|
|
848
|
+
amount?: number | null;
|
|
849
|
+
currency?: string;
|
|
850
|
+
context?: string;
|
|
851
|
+
}
|
|
852
|
+
export interface PublicSignupPaymentAgentWallet {
|
|
853
|
+
supported?: boolean;
|
|
854
|
+
how?: string;
|
|
855
|
+
spend_request?: PublicSignupPaymentAgentWalletSpendRequest;
|
|
856
|
+
}
|
|
857
|
+
export interface PublicSignupPayment {
|
|
858
|
+
amount?: number | null;
|
|
859
|
+
currency?: string;
|
|
860
|
+
amount_display?: string | null;
|
|
861
|
+
billing?: string;
|
|
862
|
+
description?: string;
|
|
863
|
+
merchant_name?: string;
|
|
864
|
+
merchant_url?: string;
|
|
865
|
+
checkout_redirect_url?: string;
|
|
866
|
+
pay_with?: string;
|
|
867
|
+
agent_wallet?: PublicSignupPaymentAgentWallet;
|
|
868
|
+
[key: string]: unknown;
|
|
824
869
|
}
|
|
825
870
|
export interface PublicSignupSession {
|
|
826
871
|
id: string;
|
|
@@ -837,6 +882,8 @@ export interface PublicSignupSession {
|
|
|
837
882
|
checkout?: Record<string, unknown>;
|
|
838
883
|
account?: Record<string, unknown>;
|
|
839
884
|
billing?: Record<string, unknown>;
|
|
885
|
+
agent_pay?: PublicSignupAgentPay | null;
|
|
886
|
+
payment?: PublicSignupPayment | null;
|
|
840
887
|
links?: Record<string, unknown>;
|
|
841
888
|
created_at?: string;
|
|
842
889
|
updated_at?: string;
|
|
@@ -856,6 +903,8 @@ export interface PublicSignupResponse {
|
|
|
856
903
|
links?: Record<string, unknown>;
|
|
857
904
|
account?: Record<string, unknown>;
|
|
858
905
|
billing?: Record<string, unknown>;
|
|
906
|
+
agent_pay?: PublicSignupAgentPay | null;
|
|
907
|
+
payment?: PublicSignupPayment | null;
|
|
859
908
|
[key: string]: unknown;
|
|
860
909
|
}
|
|
861
910
|
export interface PublicSignupSessionResponse {
|
package/dist/lib/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const POSTERLY_MCP_VERSION = "0.43.
|
|
1
|
+
export declare const POSTERLY_MCP_VERSION = "0.43.3";
|
package/dist/lib/version.js
CHANGED
|
@@ -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.43.
|
|
8
|
+
export const POSTERLY_MCP_VERSION = '0.43.3';
|
|
@@ -13,15 +13,15 @@ export declare const createWebhookTool: {
|
|
|
13
13
|
}, "strip", z.ZodTypeAny, {
|
|
14
14
|
url: string;
|
|
15
15
|
confirm: true;
|
|
16
|
-
workspace_id?: string | undefined;
|
|
17
16
|
description?: string | undefined;
|
|
17
|
+
workspace_id?: string | undefined;
|
|
18
18
|
events?: ("webhook.test" | "post.created" | "post.updated" | "post.deleted" | "post.publishing" | "post.published" | "post.failed" | "account.disconnected" | "analytics.synced")[] | undefined;
|
|
19
19
|
is_active?: boolean | undefined;
|
|
20
20
|
}, {
|
|
21
21
|
url: string;
|
|
22
22
|
confirm: true;
|
|
23
|
-
workspace_id?: string | undefined;
|
|
24
23
|
description?: string | undefined;
|
|
24
|
+
workspace_id?: string | undefined;
|
|
25
25
|
events?: ("webhook.test" | "post.created" | "post.updated" | "post.deleted" | "post.publishing" | "post.published" | "post.failed" | "account.disconnected" | "analytics.synced")[] | undefined;
|
|
26
26
|
is_active?: boolean | undefined;
|
|
27
27
|
}>;
|
|
@@ -14,8 +14,8 @@ export const getAgentSignupInfoTool = {
|
|
|
14
14
|
'',
|
|
15
15
|
'Pre-auth tools:',
|
|
16
16
|
'- get_mcp_status: checks the installed server version, latest npm version, MCP endpoint health, API auth health, and whether POSTERLY_API_KEY is configured.',
|
|
17
|
-
'- start_signup: starts paid signup and returns a
|
|
18
|
-
'- get_signup_session: polls
|
|
17
|
+
'- start_signup: starts paid signup and returns a signup poll URL, a browser Checkout fallback, and, when enabled, a prepaid PaymentIntent for a Link virtual card (credential_type: card).',
|
|
18
|
+
'- get_signup_session: polls payment, password, and agent-access status.',
|
|
19
19
|
'',
|
|
20
20
|
'After Posterly access is installed, onboard the user IN THIS chat (do not send them to /onboarding-v2):',
|
|
21
21
|
'- whoami: confirm the paid account and read onboarding.next_step.',
|
|
@@ -30,9 +30,12 @@ export const getAgentSignupInfoTool = {
|
|
|
30
30
|
'- Do not narrate raw curl, HTTP, JSON, API keys, or implementation details unless the user explicitly asks for debugging.',
|
|
31
31
|
'',
|
|
32
32
|
'Boundaries:',
|
|
33
|
-
'-
|
|
33
|
+
'- Payment happens on Stripe Checkout, either by the user in their browser or by the agent with its own approved payment credential (for example a Link agent wallet); never card details in chat.',
|
|
34
|
+
'- Where enabled, payment can instead be a one-time Link Agent Wallet virtual card (credential_type: card) on a prepaid PaymentIntent.',
|
|
35
|
+
'- Never send card numbers to posterly. Confirm the PaymentIntent with Stripe, or send checkout_redirect_url.',
|
|
34
36
|
'- The user sets their Posterly password in their browser.',
|
|
35
37
|
'- The user approves social OAuth in their browser.',
|
|
38
|
+
'- Publish approval stays with the user.',
|
|
36
39
|
'- The AI should never ask for card details, Posterly passwords, social passwords, or OAuth codes.',
|
|
37
40
|
].join('\n');
|
|
38
41
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
export const getSignupSessionTool = {
|
|
3
3
|
name: 'get_signup_session',
|
|
4
|
-
description: 'Poll a public Posterly signup session created by start_signup. Use this to narrate
|
|
4
|
+
description: 'Poll a public Posterly signup session created by start_signup. Use this to narrate payment (Link virtual card or browser Checkout), password setup, and agent access status before a Posterly API key is installed. Keep updates user-facing; do not narrate raw HTTP, curl, or API plumbing.',
|
|
5
5
|
inputSchema: z.object({
|
|
6
6
|
session_id: z
|
|
7
7
|
.string()
|
|
@@ -23,18 +23,32 @@ function formatSignupSession(session, includeRaw) {
|
|
|
23
23
|
const checkoutUrl = stringFromRecord(session.links, 'checkout_url');
|
|
24
24
|
const passwordUrl = stringFromRecord(session.links, 'password_setup_url');
|
|
25
25
|
const completeUrl = stringFromRecord(session.links, 'complete_url');
|
|
26
|
+
const agentPay = session.agent_pay;
|
|
27
|
+
const payment = session.payment;
|
|
26
28
|
const lines = [
|
|
27
29
|
`Posterly signup session: ${session.id}`,
|
|
28
30
|
`Status: ${session.status}`,
|
|
29
31
|
session.status_message ? `Message: ${session.status_message}` : '',
|
|
30
32
|
nextAction?.label ? `Next action: ${nextAction.label}` : '',
|
|
31
33
|
nextAction?.description ? `Next action detail: ${nextAction.description}` : '',
|
|
34
|
+
agentPay?.amount_display ? `Agent pay amount: ${agentPay.amount_display}` : '',
|
|
35
|
+
agentPay?.payment_intent_id ? `PaymentIntent: ${agentPay.payment_intent_id}` : '',
|
|
36
|
+
agentPay?.status ? `PaymentIntent status: ${agentPay.status}` : '',
|
|
37
|
+
agentPay?.requires_tos_acceptance ? 'Terms acceptance required before client_secret is released.' : '',
|
|
38
|
+
agentPay?.client_secret ? `PaymentIntent client_secret: ${agentPay.client_secret}` : '',
|
|
39
|
+
agentPay?.confirm_url ? `Confirm URL: ${agentPay.confirm_url}` : '',
|
|
40
|
+
!agentPay?.enabled && payment?.amount_display
|
|
41
|
+
? `Amount due: ${payment.amount_display} ${String(payment.currency || 'usd').toUpperCase()} to ${payment.merchant_name || 'posterly'} (${payment.billing || 'subscription'})`
|
|
42
|
+
: '',
|
|
43
|
+
!agentPay?.enabled && payment?.agent_wallet?.how
|
|
44
|
+
? `Agent wallet option: ${payment.agent_wallet.how}`
|
|
45
|
+
: '',
|
|
32
46
|
checkoutRedirectUrl ? `Checkout handoff URL: ${checkoutRedirectUrl}` : '',
|
|
33
47
|
checkoutUrl ? `Checkout URL: ${checkoutUrl}` : '',
|
|
34
48
|
passwordUrl ? `Password setup URL: ${passwordUrl}` : '',
|
|
35
49
|
completeUrl ? `Completion URL: ${completeUrl}` : '',
|
|
36
50
|
'',
|
|
37
|
-
guidanceForStatus(session.status),
|
|
51
|
+
guidanceForStatus(session.status, Boolean(agentPay?.enabled || agentPay?.payment_intent_id), Boolean(agentPay?.requires_tos_acceptance)),
|
|
38
52
|
session.agent_next_steps?.length
|
|
39
53
|
? `Agent next steps:\n${session.agent_next_steps.map((step, index) => `${index + 1}. ${step}`).join('\n')}`
|
|
40
54
|
: '',
|
|
@@ -46,10 +60,15 @@ function stringFromRecord(record, key) {
|
|
|
46
60
|
const value = record?.[key];
|
|
47
61
|
return typeof value === 'string' ? value : null;
|
|
48
62
|
}
|
|
49
|
-
function guidanceForStatus(status) {
|
|
63
|
+
function guidanceForStatus(status, agentPayAvailable = false, requiresTosAcceptance = false) {
|
|
50
64
|
switch (status) {
|
|
51
65
|
case 'checkout_pending':
|
|
52
|
-
|
|
66
|
+
if (agentPayAvailable && requiresTosAcceptance) {
|
|
67
|
+
return 'Payment is still pending on terms acceptance. Ask the user to explicitly confirm they accept the posterly terms at https://www.poster.ly/terms, then POST { "tos_accepted": true } to Confirm URL to receive client_secret, or send the user the Checkout handoff URL. Keep polling; never ask for card numbers.';
|
|
68
|
+
}
|
|
69
|
+
return agentPayAvailable
|
|
70
|
+
? 'Payment is still pending. Confirm the prepaid PaymentIntent with a Link virtual card (credential_type: card), or send the user the Checkout handoff URL. Keep polling; never ask for card numbers.'
|
|
71
|
+
: 'Tell the user checkout is still pending. If you hold an approved payment credential such as a Link agent wallet, you may pay the Checkout handoff URL yourself instead of asking the user; otherwise keep polling. Never ask for card details.';
|
|
53
72
|
case 'checkout_expired':
|
|
54
73
|
return 'Tell the user checkout expired and offer to call start_signup again.';
|
|
55
74
|
case 'payment_confirmed':
|
|
@@ -11,6 +11,7 @@ export declare const startSignupTool: {
|
|
|
11
11
|
api_addon: z.ZodDefault<z.ZodBoolean>;
|
|
12
12
|
return_path: z.ZodDefault<z.ZodString>;
|
|
13
13
|
source: z.ZodDefault<z.ZodString>;
|
|
14
|
+
tos_accepted: z.ZodOptional<z.ZodBoolean>;
|
|
14
15
|
debug: z.ZodOptional<z.ZodBoolean>;
|
|
15
16
|
}, "strip", z.ZodTypeAny, {
|
|
16
17
|
email: string;
|
|
@@ -21,6 +22,7 @@ export declare const startSignupTool: {
|
|
|
21
22
|
source: string;
|
|
22
23
|
debug?: boolean | undefined;
|
|
23
24
|
name?: string | undefined;
|
|
25
|
+
tos_accepted?: boolean | undefined;
|
|
24
26
|
}, {
|
|
25
27
|
email: string;
|
|
26
28
|
debug?: boolean | undefined;
|
|
@@ -30,6 +32,7 @@ export declare const startSignupTool: {
|
|
|
30
32
|
api_addon?: boolean | undefined;
|
|
31
33
|
return_path?: string | undefined;
|
|
32
34
|
source?: string | undefined;
|
|
35
|
+
tos_accepted?: boolean | undefined;
|
|
33
36
|
}>;
|
|
34
37
|
execute(client: PosterlyClient, input: {
|
|
35
38
|
email: string;
|
|
@@ -39,6 +42,7 @@ export declare const startSignupTool: {
|
|
|
39
42
|
api_addon?: boolean;
|
|
40
43
|
return_path?: string;
|
|
41
44
|
source?: string;
|
|
45
|
+
tos_accepted?: boolean;
|
|
42
46
|
debug?: boolean;
|
|
43
47
|
}): Promise<string>;
|
|
44
48
|
};
|
|
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
const DEFAULT_RETURN_PATH = '/dashboard/api?api_signup=success';
|
|
3
3
|
export const startSignupTool = {
|
|
4
4
|
name: 'start_signup',
|
|
5
|
-
description: 'Start the public Posterly paid signup flow for a user before Posterly API access exists. Returns a
|
|
5
|
+
description: 'Start the public Posterly paid signup flow for a user before Posterly API access exists. Returns a signup poll URL, a browser Checkout fallback URL, and, when enabled, a prepaid PaymentIntent the agent can pay with a Link Agent Wallet virtual card (credential_type: card). The user still sets a password and approves social OAuth in the browser. Never ask for card numbers, a Posterly password, or social passwords in chat.',
|
|
6
6
|
inputSchema: z.object({
|
|
7
7
|
email: z
|
|
8
8
|
.string()
|
|
@@ -32,6 +32,10 @@ export const startSignupTool = {
|
|
|
32
32
|
.string()
|
|
33
33
|
.default('posterly_mcp_pre_auth_signup')
|
|
34
34
|
.describe('Source label for analytics and support diagnostics.'),
|
|
35
|
+
tos_accepted: z
|
|
36
|
+
.boolean()
|
|
37
|
+
.optional()
|
|
38
|
+
.describe('Set true only after the user has explicitly confirmed, in this conversation, that they accept the posterly terms at https://www.poster.ly/terms. Sending it here avoids a separate terms-confirmation step before client_secret is released.'),
|
|
35
39
|
debug: z
|
|
36
40
|
.boolean()
|
|
37
41
|
.optional()
|
|
@@ -46,6 +50,7 @@ export const startSignupTool = {
|
|
|
46
50
|
api_addon: input.api_addon ?? true,
|
|
47
51
|
return_path: input.return_path ?? DEFAULT_RETURN_PATH,
|
|
48
52
|
source: input.source ?? 'posterly_mcp_pre_auth_signup',
|
|
53
|
+
tos_accepted: input.tos_accepted,
|
|
49
54
|
});
|
|
50
55
|
return formatSignupStart(response, Boolean(input.debug));
|
|
51
56
|
},
|
|
@@ -64,22 +69,58 @@ function formatSignupStart(response, includeRaw) {
|
|
|
64
69
|
const completeUrl = response.complete_url || valueFromLinks(response, 'complete_url');
|
|
65
70
|
const status = session?.status || response.status || 'checkout_pending';
|
|
66
71
|
const message = session?.status_message || response.status_message;
|
|
72
|
+
const agentPay = response.agent_pay || session?.agent_pay;
|
|
73
|
+
const payment = response.payment || session?.payment;
|
|
67
74
|
const lines = [
|
|
68
75
|
'Posterly signup started.',
|
|
69
76
|
sessionId ? `Signup session: ${sessionId}` : '',
|
|
70
77
|
`Status: ${status}`,
|
|
71
78
|
message ? `Message: ${message}` : '',
|
|
72
|
-
|
|
79
|
+
agentPay?.amount_display
|
|
80
|
+
? `Agent pay amount: ${agentPay.amount_display} ${String(agentPay.currency || 'usd').toUpperCase()}`
|
|
81
|
+
: '',
|
|
82
|
+
agentPay?.payment_intent_id ? `PaymentIntent: ${agentPay.payment_intent_id}` : '',
|
|
83
|
+
agentPay?.requires_tos_acceptance ? 'Terms acceptance required before client_secret is released.' : '',
|
|
84
|
+
agentPay?.client_secret ? `PaymentIntent client_secret: ${agentPay.client_secret}` : '',
|
|
85
|
+
agentPay?.confirm_url ? `Confirm URL: ${agentPay.confirm_url}` : '',
|
|
86
|
+
agentPay?.pay_instructions ? `Pay instructions: ${agentPay.pay_instructions}` : '',
|
|
87
|
+
!agentPay?.enabled && payment?.amount_display
|
|
88
|
+
? `Amount due: ${payment.amount_display} ${String(payment.currency || 'usd').toUpperCase()} to ${payment.merchant_name || 'posterly'} (${payment.billing || 'subscription'})`
|
|
89
|
+
: '',
|
|
90
|
+
!agentPay?.enabled && payment?.agent_wallet?.how
|
|
91
|
+
? `Agent wallet option: ${payment.agent_wallet.how}`
|
|
92
|
+
: '',
|
|
93
|
+
checkoutRedirectUrl ? `Checkout handoff URL (browser fallback): ${checkoutRedirectUrl}` : '',
|
|
73
94
|
checkoutUrl ? `Checkout URL: ${checkoutUrl}` : '',
|
|
74
95
|
pollUrl ? `Poll URL: ${pollUrl}` : '',
|
|
75
96
|
completeUrl ? `Completion URL: ${completeUrl}` : '',
|
|
76
97
|
'',
|
|
77
98
|
'Next steps for the AI agent:',
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
99
|
+
...(agentPay?.enabled && agentPay?.requires_tos_acceptance
|
|
100
|
+
? [
|
|
101
|
+
'1. Ask the user to explicitly confirm they accept the posterly terms at https://www.poster.ly/terms.',
|
|
102
|
+
'2. Once confirmed, POST { "tos_accepted": true } to Confirm URL (optionally with payment_method in the same call) to receive client_secret.',
|
|
103
|
+
'3. If the user would rather pay on the website, send them the Checkout handoff URL instead.',
|
|
104
|
+
'4. Call get_signup_session with the signup session ID until the status changes.',
|
|
105
|
+
'5. Do not ask for card details, the posterly password, social passwords, or OAuth codes.',
|
|
106
|
+
]
|
|
107
|
+
: agentPay?.enabled
|
|
108
|
+
? [
|
|
109
|
+
'1. Prefer agent_pay: confirm the PaymentIntent with a one-time Link Agent Wallet virtual card (credential_type: card). Never paste card numbers into chat or send them to posterly.',
|
|
110
|
+
'2. If the user would rather pay on the website, send them the Checkout handoff URL instead.',
|
|
111
|
+
'3. Call get_signup_session with the signup session ID until the status changes.',
|
|
112
|
+
'4. Tell the user when Posterly sends the password setup email. Password, social OAuth, and publish approval stay in the browser.',
|
|
113
|
+
'5. 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.',
|
|
114
|
+
'6. Do not ask for card details, the Posterly password, social passwords, or OAuth codes.',
|
|
115
|
+
]
|
|
116
|
+
: [
|
|
117
|
+
'1. If you hold an approved payment credential such as a Link agent wallet, you can pay the Checkout handoff URL yourself: create a spend request for the amount and merchant above, get the user\'s approval in the wallet, then complete the Checkout page with that credential. Never paste card numbers into chat or send them to posterly.',
|
|
118
|
+
'2. Otherwise, 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.',
|
|
119
|
+
'3. Call get_signup_session with the signup session ID until the status changes.',
|
|
120
|
+
'4. Tell the user when Posterly sends the password setup email.',
|
|
121
|
+
'5. 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.',
|
|
122
|
+
'6. Do not ask for card details, the Posterly password, social passwords, or OAuth codes.',
|
|
123
|
+
]),
|
|
83
124
|
includeRaw ? `\nRaw signup response:\n${JSON.stringify(response, null, 2)}` : '',
|
|
84
125
|
];
|
|
85
126
|
return lines.filter(Boolean).join('\n');
|
|
@@ -14,17 +14,17 @@ export declare const updateWebhookTool: {
|
|
|
14
14
|
}, "strip", z.ZodTypeAny, {
|
|
15
15
|
confirm: true;
|
|
16
16
|
webhook_id: string;
|
|
17
|
+
description?: string | null | undefined;
|
|
17
18
|
workspace_id?: string | null | undefined;
|
|
18
19
|
url?: string | undefined;
|
|
19
|
-
description?: string | null | undefined;
|
|
20
20
|
events?: ("webhook.test" | "post.created" | "post.updated" | "post.deleted" | "post.publishing" | "post.published" | "post.failed" | "account.disconnected" | "analytics.synced")[] | undefined;
|
|
21
21
|
is_active?: boolean | undefined;
|
|
22
22
|
}, {
|
|
23
23
|
confirm: true;
|
|
24
24
|
webhook_id: string;
|
|
25
|
+
description?: string | null | undefined;
|
|
25
26
|
workspace_id?: string | null | undefined;
|
|
26
27
|
url?: string | undefined;
|
|
27
|
-
description?: string | null | undefined;
|
|
28
28
|
events?: ("webhook.test" | "post.created" | "post.updated" | "post.deleted" | "post.publishing" | "post.published" | "post.failed" | "account.disconnected" | "analytics.synced")[] | undefined;
|
|
29
29
|
is_active?: boolean | undefined;
|
|
30
30
|
}>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "posterly-mcp-server",
|
|
3
|
-
"version": "0.43.
|
|
3
|
+
"version": "0.43.3",
|
|
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.43.
|
|
6
|
+
"version": "0.43.3",
|
|
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.43.
|
|
17
|
+
"version": "0.43.3",
|
|
18
18
|
"transport": {
|
|
19
19
|
"type": "stdio"
|
|
20
20
|
},
|
package/src/lib/api-client.ts
CHANGED
|
@@ -850,6 +850,64 @@ export interface PublicSignupPayload {
|
|
|
850
850
|
api_addon?: boolean;
|
|
851
851
|
return_path?: string;
|
|
852
852
|
source?: string;
|
|
853
|
+
// Set true only after the user has explicitly confirmed, in this
|
|
854
|
+
// conversation, that they accept the posterly terms. Sending it on this
|
|
855
|
+
// first call avoids a separate terms-confirmation round trip.
|
|
856
|
+
tos_accepted?: boolean;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
export interface PublicSignupAgentPay {
|
|
860
|
+
enabled?: boolean;
|
|
861
|
+
method?: string;
|
|
862
|
+
credential_type?: string;
|
|
863
|
+
amount?: number;
|
|
864
|
+
currency?: string;
|
|
865
|
+
amount_display?: string;
|
|
866
|
+
payment_intent_id?: string;
|
|
867
|
+
client_secret?: string | null;
|
|
868
|
+
publishable_key?: string | null;
|
|
869
|
+
confirm_url?: string;
|
|
870
|
+
poll_url?: string;
|
|
871
|
+
checkout_redirect_url?: string;
|
|
872
|
+
pay_instructions?: string;
|
|
873
|
+
status?: string;
|
|
874
|
+
period?: Record<string, unknown>;
|
|
875
|
+
// True until the user has explicitly accepted the posterly terms. While
|
|
876
|
+
// true, client_secret and publishable_key are withheld.
|
|
877
|
+
requires_tos_acceptance?: boolean;
|
|
878
|
+
[key: string]: unknown;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
export interface PublicSignupPaymentAgentWalletSpendRequest {
|
|
882
|
+
merchant_name?: string;
|
|
883
|
+
merchant_url?: string;
|
|
884
|
+
amount?: number | null;
|
|
885
|
+
currency?: string;
|
|
886
|
+
context?: string;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
export interface PublicSignupPaymentAgentWallet {
|
|
890
|
+
supported?: boolean;
|
|
891
|
+
how?: string;
|
|
892
|
+
spend_request?: PublicSignupPaymentAgentWalletSpendRequest;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
// Always present while checkout is open, regardless of agent_pay/ENABLE_AGENT_CARD_PAY.
|
|
896
|
+
// Describes the Stripe-hosted Checkout session itself so an agent with its own
|
|
897
|
+
// approved payment credential (for example a Link agent wallet) can pay it
|
|
898
|
+
// directly. null once payment is confirmed or checkout has expired.
|
|
899
|
+
export interface PublicSignupPayment {
|
|
900
|
+
amount?: number | null;
|
|
901
|
+
currency?: string;
|
|
902
|
+
amount_display?: string | null;
|
|
903
|
+
billing?: string;
|
|
904
|
+
description?: string;
|
|
905
|
+
merchant_name?: string;
|
|
906
|
+
merchant_url?: string;
|
|
907
|
+
checkout_redirect_url?: string;
|
|
908
|
+
pay_with?: string;
|
|
909
|
+
agent_wallet?: PublicSignupPaymentAgentWallet;
|
|
910
|
+
[key: string]: unknown;
|
|
853
911
|
}
|
|
854
912
|
|
|
855
913
|
export interface PublicSignupSession {
|
|
@@ -867,6 +925,8 @@ export interface PublicSignupSession {
|
|
|
867
925
|
checkout?: Record<string, unknown>;
|
|
868
926
|
account?: Record<string, unknown>;
|
|
869
927
|
billing?: Record<string, unknown>;
|
|
928
|
+
agent_pay?: PublicSignupAgentPay | null;
|
|
929
|
+
payment?: PublicSignupPayment | null;
|
|
870
930
|
links?: Record<string, unknown>;
|
|
871
931
|
created_at?: string;
|
|
872
932
|
updated_at?: string;
|
|
@@ -887,6 +947,8 @@ export interface PublicSignupResponse {
|
|
|
887
947
|
links?: Record<string, unknown>;
|
|
888
948
|
account?: Record<string, unknown>;
|
|
889
949
|
billing?: Record<string, unknown>;
|
|
950
|
+
agent_pay?: PublicSignupAgentPay | null;
|
|
951
|
+
payment?: PublicSignupPayment | null;
|
|
890
952
|
[key: string]: unknown;
|
|
891
953
|
}
|
|
892
954
|
|
package/src/lib/version.ts
CHANGED
|
@@ -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.43.
|
|
8
|
+
export const POSTERLY_MCP_VERSION = '0.43.3';
|
|
@@ -19,8 +19,8 @@ export const getAgentSignupInfoTool = {
|
|
|
19
19
|
'',
|
|
20
20
|
'Pre-auth tools:',
|
|
21
21
|
'- get_mcp_status: checks the installed server version, latest npm version, MCP endpoint health, API auth health, and whether POSTERLY_API_KEY is configured.',
|
|
22
|
-
'- start_signup: starts paid signup and returns a
|
|
23
|
-
'- get_signup_session: polls
|
|
22
|
+
'- start_signup: starts paid signup and returns a signup poll URL, a browser Checkout fallback, and, when enabled, a prepaid PaymentIntent for a Link virtual card (credential_type: card).',
|
|
23
|
+
'- get_signup_session: polls payment, password, and agent-access status.',
|
|
24
24
|
'',
|
|
25
25
|
'After Posterly access is installed, onboard the user IN THIS chat (do not send them to /onboarding-v2):',
|
|
26
26
|
'- whoami: confirm the paid account and read onboarding.next_step.',
|
|
@@ -35,9 +35,12 @@ export const getAgentSignupInfoTool = {
|
|
|
35
35
|
'- Do not narrate raw curl, HTTP, JSON, API keys, or implementation details unless the user explicitly asks for debugging.',
|
|
36
36
|
'',
|
|
37
37
|
'Boundaries:',
|
|
38
|
-
'-
|
|
38
|
+
'- Payment happens on Stripe Checkout, either by the user in their browser or by the agent with its own approved payment credential (for example a Link agent wallet); never card details in chat.',
|
|
39
|
+
'- Where enabled, payment can instead be a one-time Link Agent Wallet virtual card (credential_type: card) on a prepaid PaymentIntent.',
|
|
40
|
+
'- Never send card numbers to posterly. Confirm the PaymentIntent with Stripe, or send checkout_redirect_url.',
|
|
39
41
|
'- The user sets their Posterly password in their browser.',
|
|
40
42
|
'- The user approves social OAuth in their browser.',
|
|
43
|
+
'- Publish approval stays with the user.',
|
|
41
44
|
'- The AI should never ask for card details, Posterly passwords, social passwords, or OAuth codes.',
|
|
42
45
|
].join('\n');
|
|
43
46
|
},
|
|
@@ -4,7 +4,7 @@ import type { PosterlyClient, PublicSignupSession } from '../lib/api-client.js';
|
|
|
4
4
|
export const getSignupSessionTool = {
|
|
5
5
|
name: 'get_signup_session',
|
|
6
6
|
description:
|
|
7
|
-
'Poll a public Posterly signup session created by start_signup. Use this to narrate
|
|
7
|
+
'Poll a public Posterly signup session created by start_signup. Use this to narrate payment (Link virtual card or browser Checkout), password setup, and agent access status before a Posterly API key is installed. Keep updates user-facing; do not narrate raw HTTP, curl, or API plumbing.',
|
|
8
8
|
inputSchema: z.object({
|
|
9
9
|
session_id: z
|
|
10
10
|
.string()
|
|
@@ -28,6 +28,8 @@ function formatSignupSession(session: PublicSignupSession, includeRaw: boolean):
|
|
|
28
28
|
const checkoutUrl = stringFromRecord(session.links, 'checkout_url');
|
|
29
29
|
const passwordUrl = stringFromRecord(session.links, 'password_setup_url');
|
|
30
30
|
const completeUrl = stringFromRecord(session.links, 'complete_url');
|
|
31
|
+
const agentPay = session.agent_pay;
|
|
32
|
+
const payment = session.payment;
|
|
31
33
|
|
|
32
34
|
const lines = [
|
|
33
35
|
`Posterly signup session: ${session.id}`,
|
|
@@ -35,12 +37,28 @@ function formatSignupSession(session: PublicSignupSession, includeRaw: boolean):
|
|
|
35
37
|
session.status_message ? `Message: ${session.status_message}` : '',
|
|
36
38
|
nextAction?.label ? `Next action: ${nextAction.label}` : '',
|
|
37
39
|
nextAction?.description ? `Next action detail: ${nextAction.description}` : '',
|
|
40
|
+
agentPay?.amount_display ? `Agent pay amount: ${agentPay.amount_display}` : '',
|
|
41
|
+
agentPay?.payment_intent_id ? `PaymentIntent: ${agentPay.payment_intent_id}` : '',
|
|
42
|
+
agentPay?.status ? `PaymentIntent status: ${agentPay.status}` : '',
|
|
43
|
+
agentPay?.requires_tos_acceptance ? 'Terms acceptance required before client_secret is released.' : '',
|
|
44
|
+
agentPay?.client_secret ? `PaymentIntent client_secret: ${agentPay.client_secret}` : '',
|
|
45
|
+
agentPay?.confirm_url ? `Confirm URL: ${agentPay.confirm_url}` : '',
|
|
46
|
+
!agentPay?.enabled && payment?.amount_display
|
|
47
|
+
? `Amount due: ${payment.amount_display} ${String(payment.currency || 'usd').toUpperCase()} to ${payment.merchant_name || 'posterly'} (${payment.billing || 'subscription'})`
|
|
48
|
+
: '',
|
|
49
|
+
!agentPay?.enabled && payment?.agent_wallet?.how
|
|
50
|
+
? `Agent wallet option: ${payment.agent_wallet.how}`
|
|
51
|
+
: '',
|
|
38
52
|
checkoutRedirectUrl ? `Checkout handoff URL: ${checkoutRedirectUrl}` : '',
|
|
39
53
|
checkoutUrl ? `Checkout URL: ${checkoutUrl}` : '',
|
|
40
54
|
passwordUrl ? `Password setup URL: ${passwordUrl}` : '',
|
|
41
55
|
completeUrl ? `Completion URL: ${completeUrl}` : '',
|
|
42
56
|
'',
|
|
43
|
-
guidanceForStatus(
|
|
57
|
+
guidanceForStatus(
|
|
58
|
+
session.status,
|
|
59
|
+
Boolean(agentPay?.enabled || agentPay?.payment_intent_id),
|
|
60
|
+
Boolean(agentPay?.requires_tos_acceptance),
|
|
61
|
+
),
|
|
44
62
|
session.agent_next_steps?.length
|
|
45
63
|
? `Agent next steps:\n${session.agent_next_steps.map((step, index) => `${index + 1}. ${step}`).join('\n')}`
|
|
46
64
|
: '',
|
|
@@ -55,10 +73,15 @@ function stringFromRecord(record: Record<string, unknown> | undefined, key: stri
|
|
|
55
73
|
return typeof value === 'string' ? value : null;
|
|
56
74
|
}
|
|
57
75
|
|
|
58
|
-
function guidanceForStatus(status: string): string {
|
|
76
|
+
function guidanceForStatus(status: string, agentPayAvailable = false, requiresTosAcceptance = false): string {
|
|
59
77
|
switch (status) {
|
|
60
78
|
case 'checkout_pending':
|
|
61
|
-
|
|
79
|
+
if (agentPayAvailable && requiresTosAcceptance) {
|
|
80
|
+
return 'Payment is still pending on terms acceptance. Ask the user to explicitly confirm they accept the posterly terms at https://www.poster.ly/terms, then POST { "tos_accepted": true } to Confirm URL to receive client_secret, or send the user the Checkout handoff URL. Keep polling; never ask for card numbers.';
|
|
81
|
+
}
|
|
82
|
+
return agentPayAvailable
|
|
83
|
+
? 'Payment is still pending. Confirm the prepaid PaymentIntent with a Link virtual card (credential_type: card), or send the user the Checkout handoff URL. Keep polling; never ask for card numbers.'
|
|
84
|
+
: 'Tell the user checkout is still pending. If you hold an approved payment credential such as a Link agent wallet, you may pay the Checkout handoff URL yourself instead of asking the user; otherwise keep polling. Never ask for card details.';
|
|
62
85
|
case 'checkout_expired':
|
|
63
86
|
return 'Tell the user checkout expired and offer to call start_signup again.';
|
|
64
87
|
case 'payment_confirmed':
|
|
@@ -6,7 +6,7 @@ const DEFAULT_RETURN_PATH = '/dashboard/api?api_signup=success';
|
|
|
6
6
|
export const startSignupTool = {
|
|
7
7
|
name: 'start_signup',
|
|
8
8
|
description:
|
|
9
|
-
'Start the public Posterly paid signup flow for a user before Posterly API access exists. Returns a
|
|
9
|
+
'Start the public Posterly paid signup flow for a user before Posterly API access exists. Returns a signup poll URL, a browser Checkout fallback URL, and, when enabled, a prepaid PaymentIntent the agent can pay with a Link Agent Wallet virtual card (credential_type: card). The user still sets a password and approves social OAuth in the browser. Never ask for card numbers, a Posterly password, or social passwords in chat.',
|
|
10
10
|
inputSchema: z.object({
|
|
11
11
|
email: z
|
|
12
12
|
.string()
|
|
@@ -36,6 +36,10 @@ export const startSignupTool = {
|
|
|
36
36
|
.string()
|
|
37
37
|
.default('posterly_mcp_pre_auth_signup')
|
|
38
38
|
.describe('Source label for analytics and support diagnostics.'),
|
|
39
|
+
tos_accepted: z
|
|
40
|
+
.boolean()
|
|
41
|
+
.optional()
|
|
42
|
+
.describe('Set true only after the user has explicitly confirmed, in this conversation, that they accept the posterly terms at https://www.poster.ly/terms. Sending it here avoids a separate terms-confirmation step before client_secret is released.'),
|
|
39
43
|
debug: z
|
|
40
44
|
.boolean()
|
|
41
45
|
.optional()
|
|
@@ -52,6 +56,7 @@ export const startSignupTool = {
|
|
|
52
56
|
api_addon?: boolean;
|
|
53
57
|
return_path?: string;
|
|
54
58
|
source?: string;
|
|
59
|
+
tos_accepted?: boolean;
|
|
55
60
|
debug?: boolean;
|
|
56
61
|
},
|
|
57
62
|
) {
|
|
@@ -63,6 +68,7 @@ export const startSignupTool = {
|
|
|
63
68
|
api_addon: input.api_addon ?? true,
|
|
64
69
|
return_path: input.return_path ?? DEFAULT_RETURN_PATH,
|
|
65
70
|
source: input.source ?? 'posterly_mcp_pre_auth_signup',
|
|
71
|
+
tos_accepted: input.tos_accepted,
|
|
66
72
|
});
|
|
67
73
|
|
|
68
74
|
return formatSignupStart(response, Boolean(input.debug));
|
|
@@ -84,23 +90,59 @@ function formatSignupStart(response: PublicSignupResponse, includeRaw: boolean):
|
|
|
84
90
|
const completeUrl = response.complete_url || valueFromLinks(response, 'complete_url');
|
|
85
91
|
const status = session?.status || response.status || 'checkout_pending';
|
|
86
92
|
const message = session?.status_message || response.status_message;
|
|
93
|
+
const agentPay = response.agent_pay || session?.agent_pay;
|
|
94
|
+
const payment = response.payment || session?.payment;
|
|
87
95
|
|
|
88
96
|
const lines = [
|
|
89
97
|
'Posterly signup started.',
|
|
90
98
|
sessionId ? `Signup session: ${sessionId}` : '',
|
|
91
99
|
`Status: ${status}`,
|
|
92
100
|
message ? `Message: ${message}` : '',
|
|
93
|
-
|
|
101
|
+
agentPay?.amount_display
|
|
102
|
+
? `Agent pay amount: ${agentPay.amount_display} ${String(agentPay.currency || 'usd').toUpperCase()}`
|
|
103
|
+
: '',
|
|
104
|
+
agentPay?.payment_intent_id ? `PaymentIntent: ${agentPay.payment_intent_id}` : '',
|
|
105
|
+
agentPay?.requires_tos_acceptance ? 'Terms acceptance required before client_secret is released.' : '',
|
|
106
|
+
agentPay?.client_secret ? `PaymentIntent client_secret: ${agentPay.client_secret}` : '',
|
|
107
|
+
agentPay?.confirm_url ? `Confirm URL: ${agentPay.confirm_url}` : '',
|
|
108
|
+
agentPay?.pay_instructions ? `Pay instructions: ${agentPay.pay_instructions}` : '',
|
|
109
|
+
!agentPay?.enabled && payment?.amount_display
|
|
110
|
+
? `Amount due: ${payment.amount_display} ${String(payment.currency || 'usd').toUpperCase()} to ${payment.merchant_name || 'posterly'} (${payment.billing || 'subscription'})`
|
|
111
|
+
: '',
|
|
112
|
+
!agentPay?.enabled && payment?.agent_wallet?.how
|
|
113
|
+
? `Agent wallet option: ${payment.agent_wallet.how}`
|
|
114
|
+
: '',
|
|
115
|
+
checkoutRedirectUrl ? `Checkout handoff URL (browser fallback): ${checkoutRedirectUrl}` : '',
|
|
94
116
|
checkoutUrl ? `Checkout URL: ${checkoutUrl}` : '',
|
|
95
117
|
pollUrl ? `Poll URL: ${pollUrl}` : '',
|
|
96
118
|
completeUrl ? `Completion URL: ${completeUrl}` : '',
|
|
97
119
|
'',
|
|
98
120
|
'Next steps for the AI agent:',
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
121
|
+
...(agentPay?.enabled && agentPay?.requires_tos_acceptance
|
|
122
|
+
? [
|
|
123
|
+
'1. Ask the user to explicitly confirm they accept the posterly terms at https://www.poster.ly/terms.',
|
|
124
|
+
'2. Once confirmed, POST { "tos_accepted": true } to Confirm URL (optionally with payment_method in the same call) to receive client_secret.',
|
|
125
|
+
'3. If the user would rather pay on the website, send them the Checkout handoff URL instead.',
|
|
126
|
+
'4. Call get_signup_session with the signup session ID until the status changes.',
|
|
127
|
+
'5. Do not ask for card details, the posterly password, social passwords, or OAuth codes.',
|
|
128
|
+
]
|
|
129
|
+
: agentPay?.enabled
|
|
130
|
+
? [
|
|
131
|
+
'1. Prefer agent_pay: confirm the PaymentIntent with a one-time Link Agent Wallet virtual card (credential_type: card). Never paste card numbers into chat or send them to posterly.',
|
|
132
|
+
'2. If the user would rather pay on the website, send them the Checkout handoff URL instead.',
|
|
133
|
+
'3. Call get_signup_session with the signup session ID until the status changes.',
|
|
134
|
+
'4. Tell the user when Posterly sends the password setup email. Password, social OAuth, and publish approval stay in the browser.',
|
|
135
|
+
'5. 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.',
|
|
136
|
+
'6. Do not ask for card details, the Posterly password, social passwords, or OAuth codes.',
|
|
137
|
+
]
|
|
138
|
+
: [
|
|
139
|
+
'1. If you hold an approved payment credential such as a Link agent wallet, you can pay the Checkout handoff URL yourself: create a spend request for the amount and merchant above, get the user\'s approval in the wallet, then complete the Checkout page with that credential. Never paste card numbers into chat or send them to posterly.',
|
|
140
|
+
'2. Otherwise, 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.',
|
|
141
|
+
'3. Call get_signup_session with the signup session ID until the status changes.',
|
|
142
|
+
'4. Tell the user when Posterly sends the password setup email.',
|
|
143
|
+
'5. 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.',
|
|
144
|
+
'6. Do not ask for card details, the Posterly password, social passwords, or OAuth codes.',
|
|
145
|
+
]),
|
|
104
146
|
includeRaw ? `\nRaw signup response:\n${JSON.stringify(response, null, 2)}` : '',
|
|
105
147
|
];
|
|
106
148
|
|