@sellable/mcp 0.1.364 → 0.1.366
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.
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
export type WorkspaceExportDataset = "people" | "events";
|
|
2
|
+
export type WorkspaceExportIntent = "reached_out_people" | "people_and_events" | "outreach_event_log" | "dashboard_messages" | "connections_sent";
|
|
3
|
+
type WorkspaceExportActionType = "INVITE" | "DM" | "INMAIL_OPEN" | "INMAIL_CLOSED" | "VIEW_PROFILE" | "COMMENT";
|
|
2
4
|
export interface ExportWorkspaceCsvInput {
|
|
3
5
|
exportType?: "outreach";
|
|
6
|
+
exportIntent?: WorkspaceExportIntent;
|
|
4
7
|
datasets?: WorkspaceExportDataset[];
|
|
8
|
+
actionTypes?: WorkspaceExportActionType[];
|
|
5
9
|
outputDir?: string;
|
|
6
10
|
fromSentAt?: string;
|
|
7
11
|
toSentAt?: string;
|
|
@@ -19,6 +23,11 @@ export declare const workspaceExportToolDefinitions: {
|
|
|
19
23
|
enum: string[];
|
|
20
24
|
description: string;
|
|
21
25
|
};
|
|
26
|
+
exportIntent: {
|
|
27
|
+
type: string;
|
|
28
|
+
enum: string[];
|
|
29
|
+
description: string;
|
|
30
|
+
};
|
|
22
31
|
datasets: {
|
|
23
32
|
type: string;
|
|
24
33
|
items: {
|
|
@@ -27,6 +36,14 @@ export declare const workspaceExportToolDefinitions: {
|
|
|
27
36
|
};
|
|
28
37
|
description: string;
|
|
29
38
|
};
|
|
39
|
+
actionTypes: {
|
|
40
|
+
type: string;
|
|
41
|
+
items: {
|
|
42
|
+
type: string;
|
|
43
|
+
enum: string[];
|
|
44
|
+
};
|
|
45
|
+
description: string;
|
|
46
|
+
};
|
|
30
47
|
outputDir: {
|
|
31
48
|
type: string;
|
|
32
49
|
description: string;
|
|
@@ -70,6 +87,16 @@ export declare function exportWorkspaceCsv(input?: ExportWorkspaceCsvInput): Pro
|
|
|
70
87
|
status: "complete" | "failed";
|
|
71
88
|
}[];
|
|
72
89
|
exportCutoff: string;
|
|
90
|
+
exportIntent: WorkspaceExportIntent | null;
|
|
91
|
+
intentDescription: string | null;
|
|
92
|
+
countDefinitions: {
|
|
93
|
+
reachedOutPeople: string;
|
|
94
|
+
outreachEvents: string;
|
|
95
|
+
dashboardMessagesSent: string;
|
|
96
|
+
connectionsSent: string;
|
|
97
|
+
profileViews: string;
|
|
98
|
+
};
|
|
99
|
+
counts: Record<string, unknown>;
|
|
73
100
|
workspace: {
|
|
74
101
|
id?: string;
|
|
75
102
|
name?: string | null;
|
|
@@ -80,3 +107,4 @@ export declare function exportWorkspaceCsv(input?: ExportWorkspaceCsvInput): Pro
|
|
|
80
107
|
error: string;
|
|
81
108
|
}[];
|
|
82
109
|
}>;
|
|
110
|
+
export {};
|
|
@@ -11,7 +11,13 @@ export const workspaceExportToolDefinitions = [
|
|
|
11
11
|
{
|
|
12
12
|
name: "export_workspace_csv",
|
|
13
13
|
description: "Export active-workspace outreach CSVs to local files on the MCP host. " +
|
|
14
|
-
"
|
|
14
|
+
"Use exportIntent to disambiguate counts before exporting: " +
|
|
15
|
+
"`reached_out_people` means one deduped row per unique prospect who received an actual contact attempt (invite, DM, open InMail, or paid/closed InMail) and is the right choice for 'everyone we reached out to'; " +
|
|
16
|
+
"`dashboard_messages` means message events only (DMs + InMails), matching the dashboard Messages Sent card; " +
|
|
17
|
+
"`connections_sent` means invite events only; " +
|
|
18
|
+
"`outreach_event_log` means one row per action event for audit/reconciliation; " +
|
|
19
|
+
"`people_and_events` exports the reached-out people CSV plus matching contact event rows. " +
|
|
20
|
+
"If the user asks for 'sent', 'reached out', or cites conflicting dashboard/export numbers, ask which intent they want before calling the tool. " +
|
|
15
21
|
"Requires a valid Sellable API key plus active workspace; run list_workspaces and set_active_workspace first if needed. " +
|
|
16
22
|
"The manifest includes file paths, counts, filters, package/runtime metadata, and skipped/deferred scope notes. " +
|
|
17
23
|
"CSV files may contain prospect and outreach metadata, so store them appropriately.",
|
|
@@ -23,10 +29,36 @@ export const workspaceExportToolDefinitions = [
|
|
|
23
29
|
enum: ["outreach"],
|
|
24
30
|
description: "Export family. Phase 70 supports outreach only.",
|
|
25
31
|
},
|
|
32
|
+
exportIntent: {
|
|
33
|
+
type: "string",
|
|
34
|
+
enum: [
|
|
35
|
+
"reached_out_people",
|
|
36
|
+
"people_and_events",
|
|
37
|
+
"outreach_event_log",
|
|
38
|
+
"dashboard_messages",
|
|
39
|
+
"connections_sent",
|
|
40
|
+
],
|
|
41
|
+
description: "Recommended semantic export. Use reached_out_people for 'everyone we reached out to'; dashboard_messages for the dashboard Messages Sent card; connections_sent for invites; outreach_event_log for audit rows; people_and_events for both reached people and matching contact events.",
|
|
42
|
+
},
|
|
26
43
|
datasets: {
|
|
27
44
|
type: "array",
|
|
28
45
|
items: { type: "string", enum: ["people", "events"] },
|
|
29
|
-
description: "
|
|
46
|
+
description: "Low-level datasets to export. people is one deduped prospect row; events is one action row. Omit this and use exportIntent for clearer behavior.",
|
|
47
|
+
},
|
|
48
|
+
actionTypes: {
|
|
49
|
+
type: "array",
|
|
50
|
+
items: {
|
|
51
|
+
type: "string",
|
|
52
|
+
enum: [
|
|
53
|
+
"INVITE",
|
|
54
|
+
"DM",
|
|
55
|
+
"INMAIL_OPEN",
|
|
56
|
+
"INMAIL_CLOSED",
|
|
57
|
+
"VIEW_PROFILE",
|
|
58
|
+
"COMMENT",
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
description: "Optional low-level action filter. Usually omit and use exportIntent. Dashboard messages are DM + INMAIL_OPEN + INMAIL_CLOSED; reached-out/contact events are INVITE + DM + INMAIL_OPEN + INMAIL_CLOSED.",
|
|
30
62
|
},
|
|
31
63
|
outputDir: {
|
|
32
64
|
type: "string",
|
|
@@ -56,6 +88,52 @@ export const workspaceExportToolDefinitions = [
|
|
|
56
88
|
},
|
|
57
89
|
},
|
|
58
90
|
];
|
|
91
|
+
const CONTACT_ACTION_TYPES = [
|
|
92
|
+
"INVITE",
|
|
93
|
+
"DM",
|
|
94
|
+
"INMAIL_OPEN",
|
|
95
|
+
"INMAIL_CLOSED",
|
|
96
|
+
];
|
|
97
|
+
const DASHBOARD_MESSAGE_ACTION_TYPES = [
|
|
98
|
+
"DM",
|
|
99
|
+
"INMAIL_OPEN",
|
|
100
|
+
"INMAIL_CLOSED",
|
|
101
|
+
];
|
|
102
|
+
const ALL_ACTION_TYPES = [
|
|
103
|
+
"INVITE",
|
|
104
|
+
"DM",
|
|
105
|
+
"INMAIL_OPEN",
|
|
106
|
+
"INMAIL_CLOSED",
|
|
107
|
+
"VIEW_PROFILE",
|
|
108
|
+
"COMMENT",
|
|
109
|
+
];
|
|
110
|
+
const EXPORT_INTENT_CONFIG = {
|
|
111
|
+
reached_out_people: {
|
|
112
|
+
datasets: ["people"],
|
|
113
|
+
actionTypes: CONTACT_ACTION_TYPES,
|
|
114
|
+
description: "Unique prospects who received at least one actual contact attempt: invite, DM, open InMail, or paid/closed InMail.",
|
|
115
|
+
},
|
|
116
|
+
people_and_events: {
|
|
117
|
+
datasets: ["people", "events"],
|
|
118
|
+
actionTypes: CONTACT_ACTION_TYPES,
|
|
119
|
+
description: "Reached-out people plus one matching contact event row per invite, DM, open InMail, or paid/closed InMail.",
|
|
120
|
+
},
|
|
121
|
+
outreach_event_log: {
|
|
122
|
+
datasets: ["events"],
|
|
123
|
+
actionTypes: ALL_ACTION_TYPES,
|
|
124
|
+
description: "Raw workflow-table-backed action event log for audit/reconciliation, including profile views and comments when present.",
|
|
125
|
+
},
|
|
126
|
+
dashboard_messages: {
|
|
127
|
+
datasets: ["events"],
|
|
128
|
+
actionTypes: DASHBOARD_MESSAGE_ACTION_TYPES,
|
|
129
|
+
description: "Message events only, matching the dashboard Messages Sent card: DMs + open InMails + paid/closed InMails.",
|
|
130
|
+
},
|
|
131
|
+
connections_sent: {
|
|
132
|
+
datasets: ["events"],
|
|
133
|
+
actionTypes: ["INVITE"],
|
|
134
|
+
description: "Connection invite events only, matching the dashboard Connections Sent sub-count.",
|
|
135
|
+
},
|
|
136
|
+
};
|
|
59
137
|
function assertIsoDate(value, field) {
|
|
60
138
|
if (value === undefined || value === null || value === "")
|
|
61
139
|
return undefined;
|
|
@@ -97,17 +175,57 @@ function normalizeDatasets(value) {
|
|
|
97
175
|
return dataset;
|
|
98
176
|
});
|
|
99
177
|
}
|
|
178
|
+
function normalizeExportIntent(value) {
|
|
179
|
+
if (value === undefined || value === null || value === "")
|
|
180
|
+
return undefined;
|
|
181
|
+
if (value !== "reached_out_people" &&
|
|
182
|
+
value !== "people_and_events" &&
|
|
183
|
+
value !== "outreach_event_log" &&
|
|
184
|
+
value !== "dashboard_messages" &&
|
|
185
|
+
value !== "connections_sent") {
|
|
186
|
+
throw new Error("exportIntent is not supported");
|
|
187
|
+
}
|
|
188
|
+
return value;
|
|
189
|
+
}
|
|
190
|
+
function normalizeActionTypes(value) {
|
|
191
|
+
if (value === undefined || value === null)
|
|
192
|
+
return [];
|
|
193
|
+
if (!Array.isArray(value))
|
|
194
|
+
throw new Error("actionTypes must be an array");
|
|
195
|
+
if (value.length === 0)
|
|
196
|
+
throw new Error("actionTypes cannot be empty");
|
|
197
|
+
const unique = Array.from(new Set(value));
|
|
198
|
+
return unique.map((actionType) => {
|
|
199
|
+
if (actionType !== "INVITE" &&
|
|
200
|
+
actionType !== "DM" &&
|
|
201
|
+
actionType !== "INMAIL_OPEN" &&
|
|
202
|
+
actionType !== "INMAIL_CLOSED" &&
|
|
203
|
+
actionType !== "VIEW_PROFILE" &&
|
|
204
|
+
actionType !== "COMMENT") {
|
|
205
|
+
throw new Error("actionTypes contains an unsupported action type");
|
|
206
|
+
}
|
|
207
|
+
return actionType;
|
|
208
|
+
});
|
|
209
|
+
}
|
|
100
210
|
function validateInput(input) {
|
|
101
211
|
if (input.exportType && input.exportType !== "outreach") {
|
|
102
212
|
throw new Error("exportType must be outreach");
|
|
103
213
|
}
|
|
214
|
+
const exportIntent = normalizeExportIntent(input.exportIntent);
|
|
215
|
+
const intentConfig = exportIntent ? EXPORT_INTENT_CONFIG[exportIntent] : null;
|
|
104
216
|
const fromSentAt = assertIsoDate(input.fromSentAt, "fromSentAt");
|
|
105
217
|
const toSentAt = assertIsoDate(input.toSentAt, "toSentAt");
|
|
106
218
|
if (fromSentAt && toSentAt && new Date(fromSentAt) > new Date(toSentAt)) {
|
|
107
219
|
throw new Error("fromSentAt must be before toSentAt");
|
|
108
220
|
}
|
|
221
|
+
const actionTypes = normalizeActionTypes(input.actionTypes);
|
|
109
222
|
return {
|
|
110
|
-
|
|
223
|
+
exportIntent,
|
|
224
|
+
intentDescription: intentConfig?.description ?? null,
|
|
225
|
+
datasets: input.datasets === undefined || input.datasets === null
|
|
226
|
+
? (intentConfig?.datasets ?? ["people", "events"])
|
|
227
|
+
: normalizeDatasets(input.datasets),
|
|
228
|
+
actionTypes: actionTypes.length > 0 ? actionTypes : (intentConfig?.actionTypes ?? []),
|
|
111
229
|
outputDir: input.outputDir,
|
|
112
230
|
fromSentAt,
|
|
113
231
|
toSentAt,
|
|
@@ -115,6 +233,15 @@ function validateInput(input) {
|
|
|
115
233
|
tableIds: assertIdList(input.tableIds, "tableIds"),
|
|
116
234
|
};
|
|
117
235
|
}
|
|
236
|
+
function countDefinitions() {
|
|
237
|
+
return {
|
|
238
|
+
reachedOutPeople: "Deduped prospects with at least one actual contact attempt: INVITE, DM, INMAIL_OPEN, or INMAIL_CLOSED. This is what 'everyone we reached out to' should mean.",
|
|
239
|
+
outreachEvents: "One row per exported LinkedInOutreach action event after workspace, date, campaign/table, and action-type filters.",
|
|
240
|
+
dashboardMessagesSent: "Dashboard Messages Sent equals DM + INMAIL_OPEN + INMAIL_CLOSED events. It excludes connection invites.",
|
|
241
|
+
connectionsSent: "Dashboard Connections Sent equals INVITE events. Accepted invites show separately as Connections Made.",
|
|
242
|
+
profileViews: "VIEW_PROFILE is an action event for audit logs, but it is not a contact attempt and should not define reached-out people.",
|
|
243
|
+
};
|
|
244
|
+
}
|
|
118
245
|
async function packageVersion() {
|
|
119
246
|
const entryDir = process.argv[1]
|
|
120
247
|
? path.dirname(path.resolve(process.argv[1]))
|
|
@@ -226,6 +353,7 @@ export async function exportWorkspaceCsv(input = {}) {
|
|
|
226
353
|
toSentAt: validated.toSentAt,
|
|
227
354
|
campaignIds: validated.campaignIds,
|
|
228
355
|
tableIds: validated.tableIds,
|
|
356
|
+
actionTypes: validated.actionTypes,
|
|
229
357
|
});
|
|
230
358
|
const metadataEndpoint = `/api/v3/mcp/workspace-export/outreach/metadata${metadataQuery}`;
|
|
231
359
|
const backendMetadata = await api.get(metadataEndpoint);
|
|
@@ -243,6 +371,7 @@ export async function exportWorkspaceCsv(input = {}) {
|
|
|
243
371
|
toSentAt: validated.toSentAt,
|
|
244
372
|
campaignIds: validated.campaignIds,
|
|
245
373
|
tableIds: validated.tableIds,
|
|
374
|
+
actionTypes: validated.actionTypes,
|
|
246
375
|
});
|
|
247
376
|
const endpoint = `/api/v3/mcp/workspace-export/outreach${query}`;
|
|
248
377
|
const filePath = path.join(runDir, `outreach-${dataset}.csv`);
|
|
@@ -278,6 +407,9 @@ export async function exportWorkspaceCsv(input = {}) {
|
|
|
278
407
|
status: failures.length > 0 ? "partial" : "success",
|
|
279
408
|
tool: "export_workspace_csv",
|
|
280
409
|
exportType: "outreach",
|
|
410
|
+
exportIntent: validated.exportIntent ?? "legacy_datasets",
|
|
411
|
+
intentDescription: validated.intentDescription,
|
|
412
|
+
countDefinitions: countDefinitions(),
|
|
281
413
|
startedAt,
|
|
282
414
|
completedAt: new Date().toISOString(),
|
|
283
415
|
package: {
|
|
@@ -298,6 +430,7 @@ export async function exportWorkspaceCsv(input = {}) {
|
|
|
298
430
|
toSentAt: validated.toSentAt ?? null,
|
|
299
431
|
campaignIds: validated.campaignIds,
|
|
300
432
|
tableIds: validated.tableIds,
|
|
433
|
+
actionTypes: validated.actionTypes,
|
|
301
434
|
exportCutoff,
|
|
302
435
|
},
|
|
303
436
|
outputDir: runDir,
|
|
@@ -318,6 +451,10 @@ export async function exportWorkspaceCsv(input = {}) {
|
|
|
318
451
|
status: file.status,
|
|
319
452
|
})),
|
|
320
453
|
exportCutoff,
|
|
454
|
+
exportIntent: validated.exportIntent ?? null,
|
|
455
|
+
intentDescription: validated.intentDescription,
|
|
456
|
+
countDefinitions: countDefinitions(),
|
|
457
|
+
counts: backendMetadata.counts ?? {},
|
|
321
458
|
workspace: backendMetadata.workspace ?? {
|
|
322
459
|
id: workspaceId,
|
|
323
460
|
name: config.activeWorkspaceName || config.workspaceName || null,
|