@sellable/mcp 0.1.613 → 0.1.614
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/server.js
CHANGED
|
@@ -52,7 +52,7 @@ import { addRubricItem, checkRubric, deleteRubricItem, draftRubrics, saveRubrics
|
|
|
52
52
|
import { getSchedulerFillCapacity } from "./tools/scheduler-fill-capacity.js";
|
|
53
53
|
import { runSchedulerSweep } from "./tools/scheduler-run.js";
|
|
54
54
|
import { getSenderRoutingTool, setSenderRoutingTool, } from "./tools/sender-routing.js";
|
|
55
|
-
import { getSender, listSenders, refreshPaidInmailCredits, } from "./tools/senders.js";
|
|
55
|
+
import { getSender, listSenders, refreshPaidInmailCredits, setSenderCalendarLink, } from "./tools/senders.js";
|
|
56
56
|
import { attachRecommendedSequence, attachSequence, createWorkflowTable, } from "./tools/sequencer.js";
|
|
57
57
|
import { setupEvergreenCampaigns } from "./tools/setup-evergreen-campaigns.js";
|
|
58
58
|
import { exportTableCsv, listTables } from "./tools/tables.js";
|
|
@@ -577,6 +577,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
577
577
|
case "get_sender":
|
|
578
578
|
result = await getSender(args);
|
|
579
579
|
break;
|
|
580
|
+
case "set_sender_calendar_link":
|
|
581
|
+
result = await setSenderCalendarLink(args);
|
|
582
|
+
break;
|
|
580
583
|
case "refresh_paid_inmail_credits":
|
|
581
584
|
result = await refreshPaidInmailCredits(args);
|
|
582
585
|
break;
|
package/dist/tools/registry.d.ts
CHANGED
|
@@ -2720,10 +2720,12 @@ export declare const allTools: ({
|
|
|
2720
2720
|
senderId: {
|
|
2721
2721
|
type: string;
|
|
2722
2722
|
description: string;
|
|
2723
|
+
minLength?: undefined;
|
|
2723
2724
|
};
|
|
2724
2725
|
workspaceId: {
|
|
2725
2726
|
type: string;
|
|
2726
2727
|
description: string;
|
|
2728
|
+
minLength?: undefined;
|
|
2727
2729
|
};
|
|
2728
2730
|
actionType?: undefined;
|
|
2729
2731
|
campaignId?: undefined;
|
|
@@ -2732,10 +2734,134 @@ export declare const allTools: ({
|
|
|
2732
2734
|
threshold?: undefined;
|
|
2733
2735
|
maxStalenessSeconds?: undefined;
|
|
2734
2736
|
paidInmailCreditsMaxStalenessSeconds?: undefined;
|
|
2737
|
+
calendarLink?: undefined;
|
|
2738
|
+
expectedCalendarLink?: undefined;
|
|
2739
|
+
expectedCalendarLinkRevision?: undefined;
|
|
2740
|
+
force?: undefined;
|
|
2735
2741
|
};
|
|
2736
2742
|
required: string[];
|
|
2737
2743
|
additionalProperties: boolean;
|
|
2738
2744
|
};
|
|
2745
|
+
outputSchema?: undefined;
|
|
2746
|
+
annotations?: undefined;
|
|
2747
|
+
} | {
|
|
2748
|
+
name: string;
|
|
2749
|
+
description: string;
|
|
2750
|
+
inputSchema: {
|
|
2751
|
+
type: string;
|
|
2752
|
+
properties: {
|
|
2753
|
+
senderId: {
|
|
2754
|
+
type: string;
|
|
2755
|
+
minLength: number;
|
|
2756
|
+
description?: undefined;
|
|
2757
|
+
};
|
|
2758
|
+
workspaceId: {
|
|
2759
|
+
type: string;
|
|
2760
|
+
minLength: number;
|
|
2761
|
+
description?: undefined;
|
|
2762
|
+
};
|
|
2763
|
+
calendarLink: {
|
|
2764
|
+
readonly type: readonly ["string", "null"];
|
|
2765
|
+
};
|
|
2766
|
+
expectedCalendarLink: {
|
|
2767
|
+
readonly type: readonly ["string", "null"];
|
|
2768
|
+
};
|
|
2769
|
+
expectedCalendarLinkRevision: {
|
|
2770
|
+
readonly type: readonly ["string", "null"];
|
|
2771
|
+
};
|
|
2772
|
+
force: {
|
|
2773
|
+
type: string;
|
|
2774
|
+
};
|
|
2775
|
+
actionType?: undefined;
|
|
2776
|
+
campaignId?: undefined;
|
|
2777
|
+
tableId?: undefined;
|
|
2778
|
+
columnId?: undefined;
|
|
2779
|
+
threshold?: undefined;
|
|
2780
|
+
maxStalenessSeconds?: undefined;
|
|
2781
|
+
paidInmailCreditsMaxStalenessSeconds?: undefined;
|
|
2782
|
+
};
|
|
2783
|
+
required: string[];
|
|
2784
|
+
additionalProperties: boolean;
|
|
2785
|
+
};
|
|
2786
|
+
outputSchema: {
|
|
2787
|
+
readonly type: "object";
|
|
2788
|
+
readonly oneOf: readonly [{
|
|
2789
|
+
readonly type: "object";
|
|
2790
|
+
readonly properties: {
|
|
2791
|
+
readonly ok: {
|
|
2792
|
+
readonly const: true;
|
|
2793
|
+
};
|
|
2794
|
+
readonly senderId: {
|
|
2795
|
+
readonly type: "string";
|
|
2796
|
+
};
|
|
2797
|
+
readonly workspaceId: {
|
|
2798
|
+
readonly type: "string";
|
|
2799
|
+
};
|
|
2800
|
+
readonly previousCalendarLink: {
|
|
2801
|
+
readonly type: readonly ["string", "null"];
|
|
2802
|
+
};
|
|
2803
|
+
readonly calendarLink: {
|
|
2804
|
+
readonly type: readonly ["string", "null"];
|
|
2805
|
+
};
|
|
2806
|
+
readonly previousCalendarLinkRevision: {
|
|
2807
|
+
readonly type: readonly ["string", "null"];
|
|
2808
|
+
};
|
|
2809
|
+
readonly calendarLinkRevision: {
|
|
2810
|
+
readonly type: readonly ["string", "null"];
|
|
2811
|
+
};
|
|
2812
|
+
readonly changed: {
|
|
2813
|
+
readonly type: "boolean";
|
|
2814
|
+
};
|
|
2815
|
+
readonly cleared: {
|
|
2816
|
+
readonly type: "boolean";
|
|
2817
|
+
};
|
|
2818
|
+
readonly forced: {
|
|
2819
|
+
readonly type: "boolean";
|
|
2820
|
+
};
|
|
2821
|
+
};
|
|
2822
|
+
readonly required: readonly ["ok", "senderId", "workspaceId", "previousCalendarLink", "calendarLink", "previousCalendarLinkRevision", "calendarLinkRevision", "changed", "cleared", "forced"];
|
|
2823
|
+
readonly additionalProperties: false;
|
|
2824
|
+
}, {
|
|
2825
|
+
readonly type: "object";
|
|
2826
|
+
readonly properties: {
|
|
2827
|
+
readonly ok: {
|
|
2828
|
+
readonly const: false;
|
|
2829
|
+
};
|
|
2830
|
+
readonly code: {
|
|
2831
|
+
readonly type: "string";
|
|
2832
|
+
};
|
|
2833
|
+
readonly message: {
|
|
2834
|
+
readonly type: "string";
|
|
2835
|
+
};
|
|
2836
|
+
readonly status: {
|
|
2837
|
+
readonly type: readonly ["number", "null"];
|
|
2838
|
+
};
|
|
2839
|
+
readonly authError: {
|
|
2840
|
+
readonly type: "boolean";
|
|
2841
|
+
};
|
|
2842
|
+
readonly uncertain: {
|
|
2843
|
+
readonly type: "boolean";
|
|
2844
|
+
};
|
|
2845
|
+
readonly currentCalendarLink: {
|
|
2846
|
+
readonly type: readonly ["string", "null"];
|
|
2847
|
+
};
|
|
2848
|
+
readonly currentCalendarLinkRevision: {
|
|
2849
|
+
readonly type: readonly ["string", "null"];
|
|
2850
|
+
};
|
|
2851
|
+
readonly guidance: {
|
|
2852
|
+
readonly type: readonly ["string", "null"];
|
|
2853
|
+
};
|
|
2854
|
+
};
|
|
2855
|
+
readonly required: readonly ["ok", "code", "message", "status", "authError", "uncertain", "currentCalendarLink", "currentCalendarLinkRevision", "guidance"];
|
|
2856
|
+
readonly additionalProperties: false;
|
|
2857
|
+
}];
|
|
2858
|
+
};
|
|
2859
|
+
annotations: {
|
|
2860
|
+
readOnlyHint: boolean;
|
|
2861
|
+
destructiveHint: boolean;
|
|
2862
|
+
idempotentHint: boolean;
|
|
2863
|
+
openWorldHint: boolean;
|
|
2864
|
+
};
|
|
2739
2865
|
} | {
|
|
2740
2866
|
name: string;
|
|
2741
2867
|
description: string;
|
package/dist/tools/senders.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export type SenderListItem = {
|
|
|
14
14
|
timeZone: string;
|
|
15
15
|
displayName: string;
|
|
16
16
|
linkedinProfileUrl: string | null;
|
|
17
|
+
calendarLink: string | null;
|
|
18
|
+
calendarLinkRevision: string | null;
|
|
17
19
|
verifiedAccountIdentity: VerifiedAccountIdentity | null;
|
|
18
20
|
identityProofAvailable: boolean;
|
|
19
21
|
identityMatchFields: SenderIdentityMatchField[];
|
|
@@ -70,6 +72,45 @@ export type RefreshPaidInmailCreditsResponse = {
|
|
|
70
72
|
sendMutation: boolean;
|
|
71
73
|
};
|
|
72
74
|
};
|
|
75
|
+
export type SetSenderCalendarLinkInput = {
|
|
76
|
+
senderId: string;
|
|
77
|
+
workspaceId: string;
|
|
78
|
+
calendarLink: string | null;
|
|
79
|
+
expectedCalendarLink: string | null;
|
|
80
|
+
expectedCalendarLinkRevision: string | null;
|
|
81
|
+
force?: boolean;
|
|
82
|
+
};
|
|
83
|
+
export type SetSenderCalendarLinkSuccess = {
|
|
84
|
+
ok: true;
|
|
85
|
+
senderId: string;
|
|
86
|
+
workspaceId: string;
|
|
87
|
+
previousCalendarLink: string | null;
|
|
88
|
+
calendarLink: string | null;
|
|
89
|
+
previousCalendarLinkRevision: string | null;
|
|
90
|
+
calendarLinkRevision: string | null;
|
|
91
|
+
changed: boolean;
|
|
92
|
+
cleared: boolean;
|
|
93
|
+
forced: boolean;
|
|
94
|
+
};
|
|
95
|
+
export type SetSenderCalendarLinkError = {
|
|
96
|
+
ok: false;
|
|
97
|
+
code: string;
|
|
98
|
+
message: string;
|
|
99
|
+
status: number | null;
|
|
100
|
+
authError: boolean;
|
|
101
|
+
uncertain: boolean;
|
|
102
|
+
currentCalendarLink: string | null;
|
|
103
|
+
currentCalendarLinkRevision: string | null;
|
|
104
|
+
guidance: string | null;
|
|
105
|
+
};
|
|
106
|
+
type SenderCalendarLinkToolResult = {
|
|
107
|
+
structuredContent: SetSenderCalendarLinkSuccess | SetSenderCalendarLinkError;
|
|
108
|
+
content: [{
|
|
109
|
+
type: "text";
|
|
110
|
+
text: string;
|
|
111
|
+
}];
|
|
112
|
+
isError?: true;
|
|
113
|
+
};
|
|
73
114
|
export declare const senderToolDefinitions: ({
|
|
74
115
|
name: string;
|
|
75
116
|
description: string;
|
|
@@ -79,6 +120,7 @@ export declare const senderToolDefinitions: ({
|
|
|
79
120
|
workspaceId: {
|
|
80
121
|
type: string;
|
|
81
122
|
description: string;
|
|
123
|
+
minLength?: undefined;
|
|
82
124
|
};
|
|
83
125
|
senderId?: undefined;
|
|
84
126
|
actionType?: undefined;
|
|
@@ -88,10 +130,16 @@ export declare const senderToolDefinitions: ({
|
|
|
88
130
|
threshold?: undefined;
|
|
89
131
|
maxStalenessSeconds?: undefined;
|
|
90
132
|
paidInmailCreditsMaxStalenessSeconds?: undefined;
|
|
133
|
+
calendarLink?: undefined;
|
|
134
|
+
expectedCalendarLink?: undefined;
|
|
135
|
+
expectedCalendarLinkRevision?: undefined;
|
|
136
|
+
force?: undefined;
|
|
91
137
|
};
|
|
92
138
|
required: never[];
|
|
93
139
|
additionalProperties: boolean;
|
|
94
140
|
};
|
|
141
|
+
outputSchema?: undefined;
|
|
142
|
+
annotations?: undefined;
|
|
95
143
|
} | {
|
|
96
144
|
name: string;
|
|
97
145
|
description: string;
|
|
@@ -101,10 +149,12 @@ export declare const senderToolDefinitions: ({
|
|
|
101
149
|
senderId: {
|
|
102
150
|
type: string;
|
|
103
151
|
description: string;
|
|
152
|
+
minLength?: undefined;
|
|
104
153
|
};
|
|
105
154
|
workspaceId: {
|
|
106
155
|
type: string;
|
|
107
156
|
description: string;
|
|
157
|
+
minLength?: undefined;
|
|
108
158
|
};
|
|
109
159
|
actionType?: undefined;
|
|
110
160
|
campaignId?: undefined;
|
|
@@ -113,10 +163,16 @@ export declare const senderToolDefinitions: ({
|
|
|
113
163
|
threshold?: undefined;
|
|
114
164
|
maxStalenessSeconds?: undefined;
|
|
115
165
|
paidInmailCreditsMaxStalenessSeconds?: undefined;
|
|
166
|
+
calendarLink?: undefined;
|
|
167
|
+
expectedCalendarLink?: undefined;
|
|
168
|
+
expectedCalendarLinkRevision?: undefined;
|
|
169
|
+
force?: undefined;
|
|
116
170
|
};
|
|
117
171
|
required: string[];
|
|
118
172
|
additionalProperties: boolean;
|
|
119
173
|
};
|
|
174
|
+
outputSchema?: undefined;
|
|
175
|
+
annotations?: undefined;
|
|
120
176
|
} | {
|
|
121
177
|
name: string;
|
|
122
178
|
description: string;
|
|
@@ -126,10 +182,12 @@ export declare const senderToolDefinitions: ({
|
|
|
126
182
|
senderId: {
|
|
127
183
|
type: string;
|
|
128
184
|
description: string;
|
|
185
|
+
minLength?: undefined;
|
|
129
186
|
};
|
|
130
187
|
workspaceId: {
|
|
131
188
|
type: string;
|
|
132
189
|
description: string;
|
|
190
|
+
minLength?: undefined;
|
|
133
191
|
};
|
|
134
192
|
actionType: {
|
|
135
193
|
type: string;
|
|
@@ -159,12 +217,137 @@ export declare const senderToolDefinitions: ({
|
|
|
159
217
|
type: string;
|
|
160
218
|
description: string;
|
|
161
219
|
};
|
|
220
|
+
calendarLink?: undefined;
|
|
221
|
+
expectedCalendarLink?: undefined;
|
|
222
|
+
expectedCalendarLinkRevision?: undefined;
|
|
223
|
+
force?: undefined;
|
|
224
|
+
};
|
|
225
|
+
required: string[];
|
|
226
|
+
additionalProperties: boolean;
|
|
227
|
+
};
|
|
228
|
+
outputSchema?: undefined;
|
|
229
|
+
annotations?: undefined;
|
|
230
|
+
} | {
|
|
231
|
+
name: string;
|
|
232
|
+
description: string;
|
|
233
|
+
inputSchema: {
|
|
234
|
+
type: string;
|
|
235
|
+
properties: {
|
|
236
|
+
senderId: {
|
|
237
|
+
type: string;
|
|
238
|
+
minLength: number;
|
|
239
|
+
description?: undefined;
|
|
240
|
+
};
|
|
241
|
+
workspaceId: {
|
|
242
|
+
type: string;
|
|
243
|
+
minLength: number;
|
|
244
|
+
description?: undefined;
|
|
245
|
+
};
|
|
246
|
+
calendarLink: {
|
|
247
|
+
readonly type: readonly ["string", "null"];
|
|
248
|
+
};
|
|
249
|
+
expectedCalendarLink: {
|
|
250
|
+
readonly type: readonly ["string", "null"];
|
|
251
|
+
};
|
|
252
|
+
expectedCalendarLinkRevision: {
|
|
253
|
+
readonly type: readonly ["string", "null"];
|
|
254
|
+
};
|
|
255
|
+
force: {
|
|
256
|
+
type: string;
|
|
257
|
+
};
|
|
258
|
+
actionType?: undefined;
|
|
259
|
+
campaignId?: undefined;
|
|
260
|
+
tableId?: undefined;
|
|
261
|
+
columnId?: undefined;
|
|
262
|
+
threshold?: undefined;
|
|
263
|
+
maxStalenessSeconds?: undefined;
|
|
264
|
+
paidInmailCreditsMaxStalenessSeconds?: undefined;
|
|
162
265
|
};
|
|
163
266
|
required: string[];
|
|
164
267
|
additionalProperties: boolean;
|
|
165
268
|
};
|
|
269
|
+
outputSchema: {
|
|
270
|
+
readonly type: "object";
|
|
271
|
+
readonly oneOf: readonly [{
|
|
272
|
+
readonly type: "object";
|
|
273
|
+
readonly properties: {
|
|
274
|
+
readonly ok: {
|
|
275
|
+
readonly const: true;
|
|
276
|
+
};
|
|
277
|
+
readonly senderId: {
|
|
278
|
+
readonly type: "string";
|
|
279
|
+
};
|
|
280
|
+
readonly workspaceId: {
|
|
281
|
+
readonly type: "string";
|
|
282
|
+
};
|
|
283
|
+
readonly previousCalendarLink: {
|
|
284
|
+
readonly type: readonly ["string", "null"];
|
|
285
|
+
};
|
|
286
|
+
readonly calendarLink: {
|
|
287
|
+
readonly type: readonly ["string", "null"];
|
|
288
|
+
};
|
|
289
|
+
readonly previousCalendarLinkRevision: {
|
|
290
|
+
readonly type: readonly ["string", "null"];
|
|
291
|
+
};
|
|
292
|
+
readonly calendarLinkRevision: {
|
|
293
|
+
readonly type: readonly ["string", "null"];
|
|
294
|
+
};
|
|
295
|
+
readonly changed: {
|
|
296
|
+
readonly type: "boolean";
|
|
297
|
+
};
|
|
298
|
+
readonly cleared: {
|
|
299
|
+
readonly type: "boolean";
|
|
300
|
+
};
|
|
301
|
+
readonly forced: {
|
|
302
|
+
readonly type: "boolean";
|
|
303
|
+
};
|
|
304
|
+
};
|
|
305
|
+
readonly required: readonly ["ok", "senderId", "workspaceId", "previousCalendarLink", "calendarLink", "previousCalendarLinkRevision", "calendarLinkRevision", "changed", "cleared", "forced"];
|
|
306
|
+
readonly additionalProperties: false;
|
|
307
|
+
}, {
|
|
308
|
+
readonly type: "object";
|
|
309
|
+
readonly properties: {
|
|
310
|
+
readonly ok: {
|
|
311
|
+
readonly const: false;
|
|
312
|
+
};
|
|
313
|
+
readonly code: {
|
|
314
|
+
readonly type: "string";
|
|
315
|
+
};
|
|
316
|
+
readonly message: {
|
|
317
|
+
readonly type: "string";
|
|
318
|
+
};
|
|
319
|
+
readonly status: {
|
|
320
|
+
readonly type: readonly ["number", "null"];
|
|
321
|
+
};
|
|
322
|
+
readonly authError: {
|
|
323
|
+
readonly type: "boolean";
|
|
324
|
+
};
|
|
325
|
+
readonly uncertain: {
|
|
326
|
+
readonly type: "boolean";
|
|
327
|
+
};
|
|
328
|
+
readonly currentCalendarLink: {
|
|
329
|
+
readonly type: readonly ["string", "null"];
|
|
330
|
+
};
|
|
331
|
+
readonly currentCalendarLinkRevision: {
|
|
332
|
+
readonly type: readonly ["string", "null"];
|
|
333
|
+
};
|
|
334
|
+
readonly guidance: {
|
|
335
|
+
readonly type: readonly ["string", "null"];
|
|
336
|
+
};
|
|
337
|
+
};
|
|
338
|
+
readonly required: readonly ["ok", "code", "message", "status", "authError", "uncertain", "currentCalendarLink", "currentCalendarLinkRevision", "guidance"];
|
|
339
|
+
readonly additionalProperties: false;
|
|
340
|
+
}];
|
|
341
|
+
};
|
|
342
|
+
annotations: {
|
|
343
|
+
readOnlyHint: boolean;
|
|
344
|
+
destructiveHint: boolean;
|
|
345
|
+
idempotentHint: boolean;
|
|
346
|
+
openWorldHint: boolean;
|
|
347
|
+
};
|
|
166
348
|
})[];
|
|
167
349
|
export declare function listSenders(input?: ListSendersInput): Promise<ListSendersResponse>;
|
|
350
|
+
export declare function setSenderCalendarLink(input: SetSenderCalendarLinkInput): Promise<SenderCalendarLinkToolResult>;
|
|
168
351
|
export declare function getSender(input: GetSenderInput): Promise<SenderDetailResponse>;
|
|
169
352
|
export declare function refreshPaidInmailCredits(input: RefreshPaidInmailCreditsInput): Promise<RefreshPaidInmailCreditsResponse>;
|
|
170
353
|
export {};
|
package/dist/tools/senders.js
CHANGED
|
@@ -1,6 +1,66 @@
|
|
|
1
|
-
import { getApi } from "../api.js";
|
|
1
|
+
import { getApi, SellableApiError } from "../api.js";
|
|
2
2
|
import { isLinkedInProfileInput, normalizeLinkedInProfileInput, } from "./linkedin-url.js";
|
|
3
3
|
import { normalizeExplicitWorkspaceId, workspaceRequestOptions, } from "./workspace-context.js";
|
|
4
|
+
const nullableStringSchema = { type: ["string", "null"] };
|
|
5
|
+
const setSenderCalendarLinkOutputSchema = {
|
|
6
|
+
type: "object",
|
|
7
|
+
oneOf: [
|
|
8
|
+
{
|
|
9
|
+
type: "object",
|
|
10
|
+
properties: {
|
|
11
|
+
ok: { const: true },
|
|
12
|
+
senderId: { type: "string" },
|
|
13
|
+
workspaceId: { type: "string" },
|
|
14
|
+
previousCalendarLink: nullableStringSchema,
|
|
15
|
+
calendarLink: nullableStringSchema,
|
|
16
|
+
previousCalendarLinkRevision: nullableStringSchema,
|
|
17
|
+
calendarLinkRevision: nullableStringSchema,
|
|
18
|
+
changed: { type: "boolean" },
|
|
19
|
+
cleared: { type: "boolean" },
|
|
20
|
+
forced: { type: "boolean" },
|
|
21
|
+
},
|
|
22
|
+
required: [
|
|
23
|
+
"ok",
|
|
24
|
+
"senderId",
|
|
25
|
+
"workspaceId",
|
|
26
|
+
"previousCalendarLink",
|
|
27
|
+
"calendarLink",
|
|
28
|
+
"previousCalendarLinkRevision",
|
|
29
|
+
"calendarLinkRevision",
|
|
30
|
+
"changed",
|
|
31
|
+
"cleared",
|
|
32
|
+
"forced",
|
|
33
|
+
],
|
|
34
|
+
additionalProperties: false,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: "object",
|
|
38
|
+
properties: {
|
|
39
|
+
ok: { const: false },
|
|
40
|
+
code: { type: "string" },
|
|
41
|
+
message: { type: "string" },
|
|
42
|
+
status: { type: ["number", "null"] },
|
|
43
|
+
authError: { type: "boolean" },
|
|
44
|
+
uncertain: { type: "boolean" },
|
|
45
|
+
currentCalendarLink: nullableStringSchema,
|
|
46
|
+
currentCalendarLinkRevision: nullableStringSchema,
|
|
47
|
+
guidance: nullableStringSchema,
|
|
48
|
+
},
|
|
49
|
+
required: [
|
|
50
|
+
"ok",
|
|
51
|
+
"code",
|
|
52
|
+
"message",
|
|
53
|
+
"status",
|
|
54
|
+
"authError",
|
|
55
|
+
"uncertain",
|
|
56
|
+
"currentCalendarLink",
|
|
57
|
+
"currentCalendarLinkRevision",
|
|
58
|
+
"guidance",
|
|
59
|
+
],
|
|
60
|
+
additionalProperties: false,
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
};
|
|
4
64
|
function pickString(...values) {
|
|
5
65
|
for (const value of values) {
|
|
6
66
|
if (typeof value !== "string")
|
|
@@ -11,6 +71,74 @@ function pickString(...values) {
|
|
|
11
71
|
}
|
|
12
72
|
return null;
|
|
13
73
|
}
|
|
74
|
+
function isNullableString(value) {
|
|
75
|
+
return value === null || typeof value === "string";
|
|
76
|
+
}
|
|
77
|
+
function calendarLinkToolResult(structuredContent) {
|
|
78
|
+
return {
|
|
79
|
+
structuredContent,
|
|
80
|
+
content: [{ type: "text", text: JSON.stringify(structuredContent) }],
|
|
81
|
+
...(structuredContent.ok ? {} : { isError: true }),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function calendarLinkError(values) {
|
|
85
|
+
return calendarLinkToolResult({ ok: false, ...values });
|
|
86
|
+
}
|
|
87
|
+
function parseErrorBody(body) {
|
|
88
|
+
try {
|
|
89
|
+
const parsed = JSON.parse(body);
|
|
90
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
91
|
+
? parsed
|
|
92
|
+
: null;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function safeErrorCode(value, fallback) {
|
|
99
|
+
return typeof value === "string" && /^[a-z0-9_]+$/.test(value)
|
|
100
|
+
? value
|
|
101
|
+
: fallback;
|
|
102
|
+
}
|
|
103
|
+
function canonicalConflictCalendarLink(value) {
|
|
104
|
+
if (typeof value !== "string")
|
|
105
|
+
return null;
|
|
106
|
+
let parsed;
|
|
107
|
+
try {
|
|
108
|
+
parsed = new URL(value.trim());
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
if (parsed.username !== "" || parsed.password !== "") {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
return parsed.toString();
|
|
120
|
+
}
|
|
121
|
+
function canonicalConflictRevision(value) {
|
|
122
|
+
if (typeof value !== "string")
|
|
123
|
+
return null;
|
|
124
|
+
const parsed = new Date(value);
|
|
125
|
+
if (!Number.isFinite(parsed.getTime()))
|
|
126
|
+
return null;
|
|
127
|
+
const canonical = parsed.toISOString();
|
|
128
|
+
return canonical === value ? canonical : null;
|
|
129
|
+
}
|
|
130
|
+
function isSenderCalendarLinkReceipt(value) {
|
|
131
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
132
|
+
return false;
|
|
133
|
+
const receipt = value;
|
|
134
|
+
return (isNullableString(receipt.previousCalendarLink) &&
|
|
135
|
+
isNullableString(receipt.calendarLink) &&
|
|
136
|
+
isNullableString(receipt.previousCalendarLinkRevision) &&
|
|
137
|
+
isNullableString(receipt.calendarLinkRevision) &&
|
|
138
|
+
typeof receipt.changed === "boolean" &&
|
|
139
|
+
typeof receipt.cleared === "boolean" &&
|
|
140
|
+
typeof receipt.forced === "boolean");
|
|
141
|
+
}
|
|
14
142
|
const DEFAULT_PAID_INMAIL_CREDITS_MAX_STALENESS_SECONDS = 4 * 60 * 60;
|
|
15
143
|
function numberOrNull(value) {
|
|
16
144
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
@@ -188,6 +316,36 @@ export const senderToolDefinitions = [
|
|
|
188
316
|
additionalProperties: false,
|
|
189
317
|
},
|
|
190
318
|
},
|
|
319
|
+
{
|
|
320
|
+
name: "set_sender_calendar_link",
|
|
321
|
+
description: "Set or clear one exact outbound sender's calendar booking link through Sellable's workspace-scoped compare-before-write route. Read list_senders first and pass its calendarLink and calendarLinkRevision. Use force only after the user explicitly authorizes overwriting newer state.",
|
|
322
|
+
inputSchema: {
|
|
323
|
+
type: "object",
|
|
324
|
+
properties: {
|
|
325
|
+
senderId: { type: "string", minLength: 1 },
|
|
326
|
+
workspaceId: { type: "string", minLength: 1 },
|
|
327
|
+
calendarLink: nullableStringSchema,
|
|
328
|
+
expectedCalendarLink: nullableStringSchema,
|
|
329
|
+
expectedCalendarLinkRevision: nullableStringSchema,
|
|
330
|
+
force: { type: "boolean" },
|
|
331
|
+
},
|
|
332
|
+
required: [
|
|
333
|
+
"senderId",
|
|
334
|
+
"workspaceId",
|
|
335
|
+
"calendarLink",
|
|
336
|
+
"expectedCalendarLink",
|
|
337
|
+
"expectedCalendarLinkRevision",
|
|
338
|
+
],
|
|
339
|
+
additionalProperties: false,
|
|
340
|
+
},
|
|
341
|
+
outputSchema: setSenderCalendarLinkOutputSchema,
|
|
342
|
+
annotations: {
|
|
343
|
+
readOnlyHint: false,
|
|
344
|
+
destructiveHint: true,
|
|
345
|
+
idempotentHint: true,
|
|
346
|
+
openWorldHint: false,
|
|
347
|
+
},
|
|
348
|
+
},
|
|
191
349
|
];
|
|
192
350
|
export async function listSenders(input = {}) {
|
|
193
351
|
const api = getApi();
|
|
@@ -205,6 +363,12 @@ export async function listSenders(input = {}) {
|
|
|
205
363
|
timeZone: String(s?.timeZone || ""),
|
|
206
364
|
displayName: computeDisplayName(s),
|
|
207
365
|
linkedinProfileUrl,
|
|
366
|
+
calendarLink: isNullableString(s?.replySettings?.calendarLink)
|
|
367
|
+
? s.replySettings.calendarLink
|
|
368
|
+
: null,
|
|
369
|
+
calendarLinkRevision: isNullableString(s?.replySettings?.calendarLinkRevision)
|
|
370
|
+
? s.replySettings.calendarLinkRevision
|
|
371
|
+
: null,
|
|
208
372
|
verifiedAccountIdentity: identity.verifiedAccountIdentity,
|
|
209
373
|
identityProofAvailable: identity.identityMatchFields.length > 0,
|
|
210
374
|
identityMatchFields: identity.identityMatchFields,
|
|
@@ -213,6 +377,127 @@ export async function listSenders(input = {}) {
|
|
|
213
377
|
}),
|
|
214
378
|
};
|
|
215
379
|
}
|
|
380
|
+
export async function setSenderCalendarLink(input) {
|
|
381
|
+
const candidate = input;
|
|
382
|
+
const record = candidate && typeof candidate === "object" && !Array.isArray(candidate)
|
|
383
|
+
? candidate
|
|
384
|
+
: null;
|
|
385
|
+
const senderId = record && typeof record.senderId === "string"
|
|
386
|
+
? record.senderId.trim()
|
|
387
|
+
: "";
|
|
388
|
+
const workspaceId = record && typeof record.workspaceId === "string"
|
|
389
|
+
? record.workspaceId.trim()
|
|
390
|
+
: "";
|
|
391
|
+
const hasOwn = (key) => record !== null && Object.prototype.hasOwnProperty.call(record, key);
|
|
392
|
+
const valid = senderId.length > 0 &&
|
|
393
|
+
workspaceId.length > 0 &&
|
|
394
|
+
hasOwn("calendarLink") &&
|
|
395
|
+
isNullableString(record?.calendarLink) &&
|
|
396
|
+
hasOwn("expectedCalendarLink") &&
|
|
397
|
+
isNullableString(record?.expectedCalendarLink) &&
|
|
398
|
+
hasOwn("expectedCalendarLinkRevision") &&
|
|
399
|
+
isNullableString(record?.expectedCalendarLinkRevision) &&
|
|
400
|
+
(!hasOwn("force") || typeof record?.force === "boolean");
|
|
401
|
+
if (!valid || !record) {
|
|
402
|
+
return calendarLinkError({
|
|
403
|
+
code: "invalid_arguments",
|
|
404
|
+
message: "senderId, workspaceId, calendarLink, expectedCalendarLink, and expectedCalendarLinkRevision are required with the documented types.",
|
|
405
|
+
status: null,
|
|
406
|
+
authError: false,
|
|
407
|
+
uncertain: false,
|
|
408
|
+
currentCalendarLink: null,
|
|
409
|
+
currentCalendarLinkRevision: null,
|
|
410
|
+
guidance: "Read list_senders and retry with its current calendarLink and calendarLinkRevision values.",
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
const api = getApi();
|
|
414
|
+
try {
|
|
415
|
+
const rawReceipt = await api.put(`/api/v3/mcp/senders/${encodeURIComponent(senderId)}/calendar-link`, {
|
|
416
|
+
workspaceId,
|
|
417
|
+
calendarLink: record.calendarLink,
|
|
418
|
+
expectedCalendarLink: record.expectedCalendarLink,
|
|
419
|
+
expectedCalendarLinkRevision: record.expectedCalendarLinkRevision,
|
|
420
|
+
force: record.force === true,
|
|
421
|
+
}, workspaceRequestOptions(workspaceId));
|
|
422
|
+
if (!isSenderCalendarLinkReceipt(rawReceipt)) {
|
|
423
|
+
return calendarLinkError({
|
|
424
|
+
code: "malformed_sender_calendar_link_response",
|
|
425
|
+
message: "The calendar-link update returned an incomplete receipt, so the final state is uncertain.",
|
|
426
|
+
status: null,
|
|
427
|
+
authError: false,
|
|
428
|
+
uncertain: true,
|
|
429
|
+
currentCalendarLink: null,
|
|
430
|
+
currentCalendarLinkRevision: null,
|
|
431
|
+
guidance: "Reread list_senders and reconcile the sender state before retrying or forcing another write.",
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
return calendarLinkToolResult({
|
|
435
|
+
ok: true,
|
|
436
|
+
senderId,
|
|
437
|
+
workspaceId,
|
|
438
|
+
previousCalendarLink: rawReceipt.previousCalendarLink,
|
|
439
|
+
calendarLink: rawReceipt.calendarLink,
|
|
440
|
+
previousCalendarLinkRevision: rawReceipt.previousCalendarLinkRevision,
|
|
441
|
+
calendarLinkRevision: rawReceipt.calendarLinkRevision,
|
|
442
|
+
changed: rawReceipt.changed,
|
|
443
|
+
cleared: rawReceipt.cleared,
|
|
444
|
+
forced: rawReceipt.forced,
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
catch (error) {
|
|
448
|
+
if (error instanceof SellableApiError) {
|
|
449
|
+
const body = parseErrorBody(error.body);
|
|
450
|
+
const code = safeErrorCode(body?.code, `http_${error.status}`);
|
|
451
|
+
const isConflict = error.status === 409 && code === "calendar_link_conflict";
|
|
452
|
+
const uncertain = error.status >= 500;
|
|
453
|
+
const guidance = isConflict
|
|
454
|
+
? "Reread list_senders, compare the current value, and use force only after the user explicitly authorizes overwriting it."
|
|
455
|
+
: uncertain
|
|
456
|
+
? "Reread list_senders and reconcile the sender state before retrying; do not force while the result is uncertain."
|
|
457
|
+
: error.isAuthError
|
|
458
|
+
? error.guidance || "Authenticate again and retry the same scoped request."
|
|
459
|
+
: error.status === 400 && code === "precondition_required"
|
|
460
|
+
? "Reread list_senders and retry with all current comparison fields."
|
|
461
|
+
: error.status === 400
|
|
462
|
+
? "Use an HTTP(S) booking URL or null, then retry with current comparison fields."
|
|
463
|
+
: error.status === 404
|
|
464
|
+
? "Reread list_senders in the explicit workspace and select an existing sender."
|
|
465
|
+
: null;
|
|
466
|
+
return calendarLinkError({
|
|
467
|
+
code,
|
|
468
|
+
message: isConflict
|
|
469
|
+
? "The sender calendar link changed after it was read."
|
|
470
|
+
: uncertain
|
|
471
|
+
? "The calendar-link update did not complete with a confirmed result."
|
|
472
|
+
: error.isAuthError
|
|
473
|
+
? "Sellable authentication or authorization failed."
|
|
474
|
+
: error.status === 404
|
|
475
|
+
? "The sender was not found in the explicit workspace."
|
|
476
|
+
: "The sender calendar link was not updated.",
|
|
477
|
+
status: error.status,
|
|
478
|
+
authError: error.isAuthError,
|
|
479
|
+
uncertain,
|
|
480
|
+
currentCalendarLink: isConflict
|
|
481
|
+
? canonicalConflictCalendarLink(body?.currentCalendarLink)
|
|
482
|
+
: null,
|
|
483
|
+
currentCalendarLinkRevision: isConflict
|
|
484
|
+
? canonicalConflictRevision(body?.currentCalendarLinkRevision)
|
|
485
|
+
: null,
|
|
486
|
+
guidance,
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
return calendarLinkError({
|
|
490
|
+
code: "sender_calendar_link_uncertain",
|
|
491
|
+
message: "The calendar-link request ended without a confirmed response, so the final state is uncertain.",
|
|
492
|
+
status: null,
|
|
493
|
+
authError: false,
|
|
494
|
+
uncertain: true,
|
|
495
|
+
currentCalendarLink: null,
|
|
496
|
+
currentCalendarLinkRevision: null,
|
|
497
|
+
guidance: "Reread list_senders and reconcile the sender state before retrying; do not force while the result is uncertain.",
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
}
|
|
216
501
|
export async function getSender(input) {
|
|
217
502
|
const api = getApi();
|
|
218
503
|
const requestOptions = workspaceRequestOptions(input.workspaceId);
|
package/package.json
CHANGED