@maestrogtm/maestro-gtm 0.10.16

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.
Files changed (115) hide show
  1. package/dist/ai-RNHSWSNV.js +158 -0
  2. package/dist/ai-RNHSWSNV.js.map +1 -0
  3. package/dist/app-PSZH2J56.js +54 -0
  4. package/dist/app-PSZH2J56.js.map +1 -0
  5. package/dist/batch-ZCHN54YJ.js +28 -0
  6. package/dist/batch-ZCHN54YJ.js.map +1 -0
  7. package/dist/campaign-XDXQA7KX.js +119 -0
  8. package/dist/campaign-XDXQA7KX.js.map +1 -0
  9. package/dist/chunk-365Q36GF.js +54 -0
  10. package/dist/chunk-365Q36GF.js.map +1 -0
  11. package/dist/chunk-4IV6QS4U.js +122 -0
  12. package/dist/chunk-4IV6QS4U.js.map +1 -0
  13. package/dist/chunk-6GLLK5KO.js +64 -0
  14. package/dist/chunk-6GLLK5KO.js.map +1 -0
  15. package/dist/chunk-6UNBW5SN.js +686 -0
  16. package/dist/chunk-6UNBW5SN.js.map +1 -0
  17. package/dist/chunk-A7JD6EYV.js +92 -0
  18. package/dist/chunk-A7JD6EYV.js.map +1 -0
  19. package/dist/chunk-ARNVJPFM.js +139 -0
  20. package/dist/chunk-ARNVJPFM.js.map +1 -0
  21. package/dist/chunk-AX6BOEF2.js +345 -0
  22. package/dist/chunk-AX6BOEF2.js.map +1 -0
  23. package/dist/chunk-C3T7QPSO.js +507 -0
  24. package/dist/chunk-C3T7QPSO.js.map +1 -0
  25. package/dist/chunk-FG43GILY.js +46 -0
  26. package/dist/chunk-FG43GILY.js.map +1 -0
  27. package/dist/chunk-FS6DCNCA.js +139 -0
  28. package/dist/chunk-FS6DCNCA.js.map +1 -0
  29. package/dist/chunk-I6GRD4X7.js +1144 -0
  30. package/dist/chunk-I6GRD4X7.js.map +1 -0
  31. package/dist/chunk-IP34URKR.js +621 -0
  32. package/dist/chunk-IP34URKR.js.map +1 -0
  33. package/dist/chunk-JFSKOY7Z.js +252 -0
  34. package/dist/chunk-JFSKOY7Z.js.map +1 -0
  35. package/dist/chunk-M25KLO7T.js +3272 -0
  36. package/dist/chunk-M25KLO7T.js.map +1 -0
  37. package/dist/chunk-M3G2WREL.js +57 -0
  38. package/dist/chunk-M3G2WREL.js.map +1 -0
  39. package/dist/chunk-MFFACSBE.js +4266 -0
  40. package/dist/chunk-MFFACSBE.js.map +1 -0
  41. package/dist/chunk-PZ5AY32C.js +10 -0
  42. package/dist/chunk-PZ5AY32C.js.map +1 -0
  43. package/dist/chunk-QZH3XFOQ.js +2636 -0
  44. package/dist/chunk-QZH3XFOQ.js.map +1 -0
  45. package/dist/chunk-SPWDMOEU.js +1940 -0
  46. package/dist/chunk-SPWDMOEU.js.map +1 -0
  47. package/dist/chunk-TP3BZDVV.js +28 -0
  48. package/dist/chunk-TP3BZDVV.js.map +1 -0
  49. package/dist/chunk-UBJUBYSQ.js +18 -0
  50. package/dist/chunk-UBJUBYSQ.js.map +1 -0
  51. package/dist/chunk-VNKXGHWY.js +20 -0
  52. package/dist/chunk-VNKXGHWY.js.map +1 -0
  53. package/dist/chunk-WKLCPIFB.js +9862 -0
  54. package/dist/chunk-WKLCPIFB.js.map +1 -0
  55. package/dist/chunk-YV5XOXRQ.js +7 -0
  56. package/dist/chunk-YV5XOXRQ.js.map +1 -0
  57. package/dist/cli-Z3BNNJYQ.js +852 -0
  58. package/dist/cli-Z3BNNJYQ.js.map +1 -0
  59. package/dist/client-Y34LNEWN.js +8 -0
  60. package/dist/client-Y34LNEWN.js.map +1 -0
  61. package/dist/config.js +17 -0
  62. package/dist/config.js.map +1 -0
  63. package/dist/configure-XSENK4X5.js +64 -0
  64. package/dist/configure-XSENK4X5.js.map +1 -0
  65. package/dist/context.js +10 -0
  66. package/dist/context.js.map +1 -0
  67. package/dist/crm-QBNHVBYV.js +86 -0
  68. package/dist/crm-QBNHVBYV.js.map +1 -0
  69. package/dist/dfy-X3OXIYRA.js +356 -0
  70. package/dist/dfy-X3OXIYRA.js.map +1 -0
  71. package/dist/dist-LGCJKGBS.js +121 -0
  72. package/dist/dist-LGCJKGBS.js.map +1 -0
  73. package/dist/engagement-C4U7LPJH.js +463 -0
  74. package/dist/engagement-C4U7LPJH.js.map +1 -0
  75. package/dist/enrich-F5GPVZFE.js +226 -0
  76. package/dist/enrich-F5GPVZFE.js.map +1 -0
  77. package/dist/extract-DS5N6SSJ.js +155 -0
  78. package/dist/extract-DS5N6SSJ.js.map +1 -0
  79. package/dist/feedback-AIXKXNM5.js +51 -0
  80. package/dist/feedback-AIXKXNM5.js.map +1 -0
  81. package/dist/fetch-QJDSPI63.js +87 -0
  82. package/dist/fetch-QJDSPI63.js.map +1 -0
  83. package/dist/handlers.js +13 -0
  84. package/dist/handlers.js.map +1 -0
  85. package/dist/index.js +38 -0
  86. package/dist/index.js.map +1 -0
  87. package/dist/list-HL7NQQJX.js +236 -0
  88. package/dist/list-HL7NQQJX.js.map +1 -0
  89. package/dist/maestro-N7Q2JX22.js +903 -0
  90. package/dist/maestro-N7Q2JX22.js.map +1 -0
  91. package/dist/prospect-RUOT43H6.js +532 -0
  92. package/dist/prospect-RUOT43H6.js.map +1 -0
  93. package/dist/providers/factory.js +10 -0
  94. package/dist/providers/factory.js.map +1 -0
  95. package/dist/providers/registry.js +8 -0
  96. package/dist/providers/registry.js.map +1 -0
  97. package/dist/provision-FT5NWN77.js +394 -0
  98. package/dist/provision-FT5NWN77.js.map +1 -0
  99. package/dist/recipe-JU3SXMZF.js +137 -0
  100. package/dist/recipe-JU3SXMZF.js.map +1 -0
  101. package/dist/review-5SB6DYDZ.js +70 -0
  102. package/dist/review-5SB6DYDZ.js.map +1 -0
  103. package/dist/sdk-LVBHNQ6T.js +3852 -0
  104. package/dist/sdk-LVBHNQ6T.js.map +1 -0
  105. package/dist/server-REKYQZ2E.js +22 -0
  106. package/dist/server-REKYQZ2E.js.map +1 -0
  107. package/dist/status-V3EEFS7S.js +114 -0
  108. package/dist/status-V3EEFS7S.js.map +1 -0
  109. package/dist/tam-J6NDBP5W.js +682 -0
  110. package/dist/tam-J6NDBP5W.js.map +1 -0
  111. package/dist/tools.js +80 -0
  112. package/dist/tools.js.map +1 -0
  113. package/dist/validation.js +12 -0
  114. package/dist/validation.js.map +1 -0
  115. package/package.json +77 -0
@@ -0,0 +1,3272 @@
1
+ // src/tools/prospect.ts
2
+ var prospectTools = [
3
+ {
4
+ name: "find_companies",
5
+ description: 'Discover companies matching ICP criteria via DiscoLike, Apollo, StoreLeads, or Exa (semantic/neural search). Use provider: "exa" for meaning-based search that understands intent, not just keywords.',
6
+ inputSchema: {
7
+ type: "object",
8
+ properties: {
9
+ icp_text: {
10
+ type: "string",
11
+ description: 'Natural language ICP description (e.g., "B2B SaaS startups in US, 50-200 employees")'
12
+ },
13
+ domain: {
14
+ type: "string",
15
+ description: "Single domain for direct company lookup"
16
+ },
17
+ domains: {
18
+ type: "array",
19
+ items: { type: "string" },
20
+ description: 'Lookalike domains to find similar companies (e.g., ["stripe.com", "plaid.com"])'
21
+ },
22
+ country: {
23
+ type: "string",
24
+ description: 'Country filter (e.g., "US", "UK", "DE")'
25
+ },
26
+ min_employees: {
27
+ type: "number",
28
+ description: "Minimum employee count"
29
+ },
30
+ max_employees: {
31
+ type: "number",
32
+ description: "Maximum employee count"
33
+ },
34
+ tech_stack: {
35
+ type: "array",
36
+ items: { type: "string" },
37
+ description: 'Filter by technology stack (e.g., ["React", "AWS"])'
38
+ },
39
+ category: {
40
+ type: "string",
41
+ description: 'Industry category filter (e.g., "SaaS", "FinTech", "Healthcare")'
42
+ },
43
+ negate_domains: {
44
+ type: "array",
45
+ items: { type: "string" },
46
+ description: "Exclude these domains from results"
47
+ },
48
+ min_digital_footprint: {
49
+ type: "number",
50
+ description: "Minimum DiscoLike digital footprint score"
51
+ },
52
+ max_digital_footprint: {
53
+ type: "number",
54
+ description: "Maximum DiscoLike digital footprint score"
55
+ },
56
+ offset: {
57
+ type: "number",
58
+ description: "Pagination offset (0-based)"
59
+ },
60
+ limit: {
61
+ type: "number",
62
+ description: "Max results to return (default: 50, max: 1000)"
63
+ },
64
+ provider: {
65
+ type: "string",
66
+ description: "Provider override: disco, apollo, storeleads (uses first available if omitted)"
67
+ },
68
+ fields: {
69
+ description: 'Response fields. Defaults to slim (domain, name, industry, employees, country). Pass "all" for full payload including description, tech_stack, score, linkedin_url.',
70
+ oneOf: [
71
+ { type: "string", enum: ["all"] },
72
+ { type: "array", items: { type: "string" } }
73
+ ]
74
+ },
75
+ search: {
76
+ type: "string",
77
+ description: "Fuzzy text match on name/description (StoreLeads provider)"
78
+ },
79
+ state: {
80
+ type: "string",
81
+ description: "US state filter (StoreLeads provider)"
82
+ },
83
+ platform: {
84
+ type: "string",
85
+ description: 'E-commerce platform filter, e.g. "Shopify" (StoreLeads provider)'
86
+ },
87
+ min_revenue: {
88
+ type: "number",
89
+ description: "Minimum estimated yearly revenue in USD (StoreLeads provider)"
90
+ },
91
+ max_revenue: {
92
+ type: "number",
93
+ description: "Maximum estimated yearly revenue in USD (StoreLeads provider)"
94
+ },
95
+ output: {
96
+ type: "string",
97
+ enum: ["file", "inline", "csv"],
98
+ description: 'Output mode. "file" writes JSONL (auto when >20 results). "csv" writes a CSV file for spreadsheet review. "inline" returns in response.'
99
+ },
100
+ detail: {
101
+ type: "string",
102
+ enum: ["summary", "full"],
103
+ description: 'Response detail level. "summary" (default) returns slim results. "full" includes applied_filters and all metadata.'
104
+ },
105
+ review: {
106
+ type: "boolean",
107
+ description: "Create a viewer table with results. Returns table_id and URL for human review. Other tools can read from this table via table_id parameter."
108
+ }
109
+ },
110
+ required: []
111
+ }
112
+ },
113
+ {
114
+ name: "find_people",
115
+ description: 'Find contacts by job title, company, or domain. Returns name, title, email, LinkedIn URL. Slim by default; pass fields: "all" for full payload. Pass enrich: true to resolve full emails inline (avoids a separate enrich call).',
116
+ inputSchema: {
117
+ type: "object",
118
+ properties: {
119
+ job_title: {
120
+ type: "string",
121
+ description: 'Job title to search for (e.g., "VP of Sales", "CEO", "Head of Marketing")'
122
+ },
123
+ company_name: {
124
+ type: "string",
125
+ description: "Company name to search within"
126
+ },
127
+ company_domain: {
128
+ type: "string",
129
+ description: 'Company domain to search within (e.g., "stripe.com")'
130
+ },
131
+ location: {
132
+ type: "string",
133
+ description: 'Location filter (e.g., "San Francisco", "United States")'
134
+ },
135
+ seniority: {
136
+ type: "array",
137
+ items: { type: "string" },
138
+ description: "Filter by seniority: owner, c_suite, vp, director, manager, senior, entry"
139
+ },
140
+ department: {
141
+ type: "array",
142
+ items: { type: "string" },
143
+ description: "Filter by department: engineering, sales, marketing, finance, hr, etc."
144
+ },
145
+ has_email: {
146
+ type: "boolean",
147
+ description: "Filter to contacts with known email (default: true)"
148
+ },
149
+ has_phone: {
150
+ type: "boolean",
151
+ description: "Filter to contacts with known phone number"
152
+ },
153
+ has_linkedin: {
154
+ type: "boolean",
155
+ description: "Filter to contacts with LinkedIn profile"
156
+ },
157
+ min_connections: {
158
+ type: "number",
159
+ description: "Minimum LinkedIn connections"
160
+ },
161
+ offset: {
162
+ type: "number",
163
+ description: "Pagination offset (0-based)"
164
+ },
165
+ limit: {
166
+ type: "number",
167
+ description: "Max results to return (default: 25, max: 1000)"
168
+ },
169
+ provider: {
170
+ type: "string",
171
+ description: "Provider override: disco, apollo (uses first available if omitted)"
172
+ },
173
+ company_domains: {
174
+ type: "array",
175
+ items: { type: "string" },
176
+ description: 'Search across multiple company domains in one call (e.g., ["stripe.com", "plaid.com"]). DiscoLike native.'
177
+ },
178
+ skills: {
179
+ type: "array",
180
+ items: { type: "string" },
181
+ description: 'Filter by skills (e.g., ["artificial intelligence", "machine learning"])'
182
+ },
183
+ filter_industry: {
184
+ type: "array",
185
+ items: { type: "string" },
186
+ description: 'Filter by company industry (e.g., ["SOFTWARE", "SAAS", "IT_SERVICES"])'
187
+ },
188
+ email_validated: {
189
+ type: "boolean",
190
+ description: "Only return contacts with validated email addresses"
191
+ },
192
+ min_employees: {
193
+ type: "number",
194
+ description: "Minimum company employee count"
195
+ },
196
+ max_employees: {
197
+ type: "number",
198
+ description: "Maximum company employee count"
199
+ },
200
+ revenue_range: {
201
+ type: "string",
202
+ description: 'Company revenue range as "min,max" (e.g., "1000000,10000000")'
203
+ },
204
+ enrich: {
205
+ type: "boolean",
206
+ description: "Resolve full email addresses inline. Some providers return masked emails (e.g., j***@company.com) in search results. Pass enrich: true to run waterfall enrichment on those contacts automatically, so you get real emails without a separate enrich call."
207
+ },
208
+ fields: {
209
+ description: 'Response fields. Defaults to slim (name, title, email, company, company_domain, linkedin). Pass "all" for full payload including skills, phone, seniority, department, connections. Or pass an array of specific field names.',
210
+ oneOf: [
211
+ { type: "string", enum: ["all"] },
212
+ { type: "array", items: { type: "string" } }
213
+ ]
214
+ },
215
+ output: {
216
+ type: "string",
217
+ enum: ["file", "inline", "csv"],
218
+ description: 'Output mode. "file" writes JSONL (auto when >20 results). "csv" writes a CSV file for spreadsheet review. "inline" returns in response.'
219
+ },
220
+ detail: {
221
+ type: "string",
222
+ enum: ["summary", "full"],
223
+ description: 'Response detail level. "summary" (default) returns slim results. "full" includes applied_filters and all metadata.'
224
+ },
225
+ review: {
226
+ type: "boolean",
227
+ description: "Create a viewer table with results. Returns table_id and URL for human review. Other tools can read from this table via table_id parameter."
228
+ }
229
+ },
230
+ required: []
231
+ }
232
+ }
233
+ ];
234
+
235
+ // src/tools/enrich.ts
236
+ var enrichTools = [
237
+ {
238
+ name: "enrich",
239
+ description: "Email/phone waterfall enrichment + single-email verification. Actions: enrich (default \u2014 waterfall enrichment, 1-100 contacts), verify (single email deliverability check). Always dry_run first for batches > 5. Defaults to email only \u2014 phone costs extra.",
240
+ inputSchema: {
241
+ type: "object",
242
+ properties: {
243
+ action: {
244
+ type: "string",
245
+ enum: ["enrich", "verify"],
246
+ description: "enrich (default) \u2014 waterfall enrichment. verify \u2014 single email deliverability check."
247
+ },
248
+ email: {
249
+ type: "string",
250
+ description: "Email address to verify (required for verify action)"
251
+ },
252
+ contacts: {
253
+ type: "array",
254
+ items: {
255
+ type: "object",
256
+ properties: {
257
+ first_name: { type: "string" },
258
+ last_name: { type: "string" },
259
+ company: { type: "string" },
260
+ company_domain: { type: "string" },
261
+ linkedin_url: { type: "string" }
262
+ },
263
+ required: ["first_name", "last_name"]
264
+ },
265
+ description: "Contacts to enrich (1-100)",
266
+ maxItems: 100
267
+ },
268
+ find: {
269
+ type: "array",
270
+ items: {
271
+ type: "string",
272
+ enum: ["email", "phone", "title", "company", "funding", "tech_stack"]
273
+ },
274
+ default: ["email"],
275
+ description: 'Fields to find. Defaults to ["email"] only. Add "phone" ONLY when explicitly requested \u2014 phone lookups cost extra. Additional fields (title, company, funding, tech_stack) return an informative error until Phase 2.'
276
+ },
277
+ waterfall: {
278
+ type: "array",
279
+ items: { type: "string" },
280
+ description: "Provider order override (uses client default if omitted)"
281
+ },
282
+ verify: { type: "boolean", default: true },
283
+ dry_run: { type: "boolean", default: false },
284
+ detail: {
285
+ type: "string",
286
+ enum: ["summary", "full"],
287
+ description: 'Response detail level. "summary" (default) returns email/phone/providers per contact. "full" includes waterfall attempt details (provider, duration, errors) per contact.'
288
+ },
289
+ table_id: {
290
+ type: "string",
291
+ description: "Read contacts from a viewer table instead of passing inline. Fetches selected rows, enriches them, and writes results back to the table."
292
+ },
293
+ review: {
294
+ type: "boolean",
295
+ description: "Create a viewer table with enrichment results."
296
+ }
297
+ },
298
+ required: []
299
+ }
300
+ },
301
+ {
302
+ name: "verify",
303
+ description: "Verify a single email address for deliverability. Returns verification status: deliverable, catch_all_safe, catch_all_not_safe, undeliverable, or unknown. Use this after enrichment or to validate an existing email.",
304
+ inputSchema: {
305
+ type: "object",
306
+ properties: {
307
+ email: {
308
+ type: "string",
309
+ description: "Email address to verify"
310
+ }
311
+ },
312
+ required: ["email"]
313
+ }
314
+ }
315
+ ];
316
+
317
+ // src/tools/extract.ts
318
+ var extractTools = [
319
+ {
320
+ name: "extract",
321
+ description: "Extract data from LinkedIn (profiles, posts, engagement, search) or web pages. HarvestAPI charges per request.",
322
+ inputSchema: {
323
+ type: "object",
324
+ required: ["type"],
325
+ properties: {
326
+ type: {
327
+ type: "string",
328
+ enum: [
329
+ "linkedin_profile",
330
+ "linkedin_posts",
331
+ "linkedin_engagement",
332
+ "linkedin_search",
333
+ "linkedin_company_posts",
334
+ "web_page"
335
+ ],
336
+ description: "Content type to extract"
337
+ },
338
+ url: {
339
+ type: "string",
340
+ description: "URL to extract data from (required for web_page)"
341
+ },
342
+ linkedin_url: {
343
+ type: "string",
344
+ description: "LinkedIn profile URL (required for linkedin_profile)"
345
+ },
346
+ find_email: {
347
+ type: "boolean",
348
+ description: "Find email via SMTP verification \u2014 uses extra credits (linkedin_profile only)"
349
+ },
350
+ profile: {
351
+ type: "string",
352
+ description: "LinkedIn URL or publicIdentifier (required for linkedin_posts)"
353
+ },
354
+ company: {
355
+ type: "string",
356
+ description: "Company LinkedIn URL or universalName (required for linkedin_company_posts)"
357
+ },
358
+ posted_within: {
359
+ type: "string",
360
+ enum: ["24h", "week", "month"],
361
+ description: "Filter posts by recency (linkedin_posts, linkedin_search, linkedin_company_posts)"
362
+ },
363
+ post_url: {
364
+ type: "string",
365
+ description: "LinkedIn post URL (required for linkedin_engagement)"
366
+ },
367
+ engagement_type: {
368
+ type: "string",
369
+ enum: ["comments", "reactions", "both"],
370
+ description: "Type of engagement to retrieve (default: both)"
371
+ },
372
+ query: {
373
+ type: "string",
374
+ description: "Keyword search (required for linkedin_search)"
375
+ },
376
+ sort: {
377
+ type: "string",
378
+ enum: ["relevance", "date"],
379
+ description: "Sort order for linkedin_search"
380
+ },
381
+ limit: { type: "number", description: "Max results to return (max 100)" },
382
+ fields: {
383
+ type: "array",
384
+ items: { type: "string" },
385
+ description: 'Specific fields to extract (e.g., ["name", "title", "company", "about"]). Extracts all available fields if omitted.'
386
+ },
387
+ detail: {
388
+ type: "string",
389
+ enum: ["summary", "full"],
390
+ description: 'Response detail level. "summary" (default) returns counts and key fields only \u2014 truncates post text, omits individual engagement items. "full" returns complete data including all post content and engager lists.'
391
+ }
392
+ }
393
+ }
394
+ }
395
+ ];
396
+
397
+ // src/tools/fetch.ts
398
+ var fetchTools = [
399
+ {
400
+ name: "fetch",
401
+ description: "Make an HTTP call to any API endpoint. Use this to pull data from services that don't have a dedicated provider.",
402
+ inputSchema: {
403
+ type: "object",
404
+ properties: {
405
+ url: { type: "string", description: "Full URL to call" },
406
+ method: {
407
+ type: "string",
408
+ enum: ["GET", "POST", "PUT", "PATCH", "DELETE"],
409
+ default: "GET"
410
+ },
411
+ headers: {
412
+ type: "object",
413
+ description: "Request headers (e.g., Authorization)"
414
+ },
415
+ body: {
416
+ type: "object",
417
+ description: "Request body (for POST/PUT/PATCH)"
418
+ },
419
+ params: {
420
+ type: "object",
421
+ description: "URL query parameters"
422
+ },
423
+ detail: {
424
+ type: "string",
425
+ enum: ["summary", "full"],
426
+ description: 'Response detail level. "summary" (default) omits response headers and truncates large bodies. "full" returns complete response including all headers.'
427
+ }
428
+ },
429
+ required: ["url"]
430
+ }
431
+ }
432
+ ];
433
+
434
+ // src/tools/ai.ts
435
+ var aiTools = [
436
+ {
437
+ name: "ai",
438
+ description: "AI-powered data operations: personalize outreach, classify leads, clean data, score prospects, or write copy. Provide an action, input data, and optional prompt. Uses your configured AI provider (Anthropic or OpenAI).",
439
+ inputSchema: {
440
+ type: "object",
441
+ properties: {
442
+ action: {
443
+ type: "string",
444
+ enum: ["personalize", "classify", "clean", "score", "write_copy"],
445
+ description: "Action type: personalize (outreach messages), classify (categorize data), clean (normalize/deduplicate), score (rank/prioritize), write_copy (generate copy)"
446
+ },
447
+ data: {
448
+ description: "Input data to process (object, array, or string)"
449
+ },
450
+ prompt: {
451
+ type: "string",
452
+ description: 'Custom instructions for the AI operation (e.g., "Write a 2-sentence cold email opener")'
453
+ },
454
+ model: {
455
+ type: "string",
456
+ description: "Model override (uses config default if omitted)"
457
+ },
458
+ enrich_with_graph: {
459
+ type: "boolean",
460
+ description: "When true and action is personalize or write_copy, auto-inject business context from the knowledge graph into the AI prompt. Requires Supabase and MAESTRO_OWNER_ID env vars."
461
+ }
462
+ },
463
+ required: ["action", "data"]
464
+ }
465
+ }
466
+ ];
467
+
468
+ // src/tools/campaign.ts
469
+ var campaignTools = [
470
+ {
471
+ name: "campaign",
472
+ description: "Provider-managed campaigns + engagement monitoring. Campaigns: list, stats, add_leads, create. Engagement: monitor (LinkedIn post scraping + auto-push), engagement_status, engagers, push. Auto-detects channel if omitted.",
473
+ inputSchema: {
474
+ type: "object",
475
+ properties: {
476
+ action: {
477
+ type: "string",
478
+ enum: [
479
+ "list",
480
+ "stats",
481
+ "add_leads",
482
+ "create",
483
+ "monitor",
484
+ "engagement_status",
485
+ "engagers",
486
+ "push"
487
+ ],
488
+ description: "Campaigns: list, stats, add_leads, create. Engagement: monitor (enable/disable scraping + auto-push), engagement_status (all monitored posts), engagers (list for a post), push (manual enrichment + push)."
489
+ },
490
+ channel: {
491
+ type: "string",
492
+ enum: ["email", "linkedin"],
493
+ description: 'Channel: "email" for cold email (PlusVibe, Instantly, SmartLead), "linkedin" for outreach (HeyReach). Auto-detects from provider/leads if omitted.'
494
+ },
495
+ campaign_id: {
496
+ type: "string",
497
+ description: "Campaign ID (required for stats and add_leads)"
498
+ },
499
+ leads: {
500
+ type: "array",
501
+ items: {
502
+ type: "object",
503
+ properties: {
504
+ email: {
505
+ type: "string",
506
+ description: "Email address (required for email campaigns)"
507
+ },
508
+ linkedin_url: {
509
+ type: "string",
510
+ description: "LinkedIn profile URL (required for LinkedIn outreach campaigns)"
511
+ },
512
+ first_name: { type: "string" },
513
+ last_name: { type: "string" },
514
+ company: { type: "string" },
515
+ custom_fields: {
516
+ type: "object",
517
+ description: "Custom merge fields for email personalization"
518
+ }
519
+ }
520
+ },
521
+ description: "Leads to add (required for add_leads action). Each lead needs at least email or linkedin_url."
522
+ },
523
+ name: {
524
+ type: "string",
525
+ description: "Campaign name (required for create action)"
526
+ },
527
+ provider: {
528
+ type: "string",
529
+ description: "Provider override (auto-selects based on available campaign_email or outreach_linkedin provider if omitted)"
530
+ },
531
+ detail: {
532
+ type: "string",
533
+ enum: ["summary", "full"],
534
+ description: 'Response detail level. "summary" (default) returns key stats only. "full" returns all campaign data.'
535
+ },
536
+ table_id: {
537
+ type: "string",
538
+ description: "Read leads from a viewer table instead of passing inline. Fetches selected rows and maps them to campaign leads."
539
+ },
540
+ // ─── Engagement params (absorbed from engagement tool) ──
541
+ post_url: {
542
+ type: "string",
543
+ description: "LinkedIn post URL \u2014 yours or external (for monitor/engagers/push)"
544
+ },
545
+ enabled: {
546
+ type: "boolean",
547
+ description: "Enable/disable engagement scraping (for monitor)"
548
+ },
549
+ plusvibe_campaign_id: {
550
+ type: "string",
551
+ description: "PlusVibe campaign ID for auto-push (for monitor)"
552
+ },
553
+ opt_in_url: {
554
+ type: "string",
555
+ description: "Lead magnet URL for {{opt_in_url}} variable (for monitor)"
556
+ },
557
+ post_topic: {
558
+ type: "string",
559
+ description: "Post topic for personalization (for monitor on external posts)"
560
+ },
561
+ creator_name: {
562
+ type: "string",
563
+ description: "Post creator name (for monitor on external posts)"
564
+ },
565
+ filter: {
566
+ type: "string",
567
+ enum: ["all", "enriched", "unenriched", "pushed", "unpushed"],
568
+ description: "Filter engagers by status (for engagers)"
569
+ },
570
+ limit: {
571
+ type: "number",
572
+ description: "Max engagers to return or push (for engagers/push)"
573
+ }
574
+ },
575
+ required: ["action"]
576
+ }
577
+ }
578
+ ];
579
+
580
+ // src/tools/crm.ts
581
+ var crmTools = [
582
+ {
583
+ name: "crm",
584
+ description: "Read and write CRM data. Find, create, or update people and companies. Create deals. Supports Attio and other CRM providers.",
585
+ inputSchema: {
586
+ type: "object",
587
+ properties: {
588
+ action: {
589
+ type: "string",
590
+ enum: ["find", "create", "update", "find_company", "create_deal"],
591
+ description: "Action to perform: find (search people by email/LinkedIn/name), create (person), update (person by id), find_company (search by name), create_deal"
592
+ },
593
+ id: {
594
+ type: "string",
595
+ description: "Person ID (required for update)"
596
+ },
597
+ query: {
598
+ type: "object",
599
+ properties: {
600
+ email: { type: "string" },
601
+ linkedin_url: { type: "string" },
602
+ name: { type: "string" }
603
+ },
604
+ description: "Search query (for find, find_company)"
605
+ },
606
+ data: {
607
+ type: "object",
608
+ properties: {
609
+ first_name: { type: "string" },
610
+ last_name: { type: "string" },
611
+ email: { type: "string" },
612
+ company: { type: "string" },
613
+ job_title: { type: "string" },
614
+ name: { type: "string", description: "Deal name (for create_deal)" },
615
+ company_id: { type: "string", description: "Associated company ID (for create_deal)" },
616
+ person_id: { type: "string", description: "Associated person ID (for create_deal)" },
617
+ stage: { type: "string", description: "Deal stage (for create_deal)" },
618
+ value: { type: "number", description: "Deal value (for create_deal)" }
619
+ },
620
+ description: "Data payload (for create, update, create_deal)"
621
+ },
622
+ provider: {
623
+ type: "string",
624
+ description: "CRM provider override (uses first available if omitted)"
625
+ },
626
+ table_id: {
627
+ type: "string",
628
+ description: "Read contacts from a viewer table for bulk create/update. Fetches selected rows and maps them to CRM person records."
629
+ }
630
+ },
631
+ required: ["action"]
632
+ }
633
+ }
634
+ ];
635
+
636
+ // src/tools/status.ts
637
+ var statusTools = [
638
+ {
639
+ name: "status",
640
+ description: "Check provider health, credit balances, and active configuration.",
641
+ inputSchema: {
642
+ type: "object",
643
+ properties: {
644
+ check: {
645
+ type: "string",
646
+ enum: ["all", "credits", "health", "config"],
647
+ default: "all",
648
+ description: "What to check: all (full status report), credits (remaining balances), health (provider connectivity), config (active client and waterfall)"
649
+ },
650
+ provider: {
651
+ type: "string",
652
+ description: "Check a specific provider only (checks all configured providers if omitted)"
653
+ },
654
+ detail: {
655
+ type: "string",
656
+ enum: ["summary", "full"],
657
+ description: 'Response detail level. "summary" (default) returns provider name, health, and credits only. "full" includes capabilities, notes, and unconfigured tool details.'
658
+ }
659
+ },
660
+ required: []
661
+ }
662
+ }
663
+ ];
664
+
665
+ // src/tools/configure.ts
666
+ var configureTools = [
667
+ {
668
+ name: "configure",
669
+ description: "System config + provider health. Config: switch_client, list_clients, show_config, set_waterfall, add_client. Status: status (provider health, credits, capabilities).",
670
+ inputSchema: {
671
+ type: "object",
672
+ properties: {
673
+ action: {
674
+ type: "string",
675
+ enum: [
676
+ "switch_client",
677
+ "list_clients",
678
+ "show_config",
679
+ "set_waterfall",
680
+ "add_client",
681
+ "status"
682
+ ],
683
+ description: "Config: switch_client, list_clients, show_config, set_waterfall, add_client. Status: status (provider health/credits)."
684
+ },
685
+ client: {
686
+ type: "string",
687
+ description: "Client name (for switch_client, add_client)"
688
+ },
689
+ email: {
690
+ type: "array",
691
+ items: { type: "string" },
692
+ description: "Email waterfall order (for set_waterfall)"
693
+ },
694
+ phone: {
695
+ type: "array",
696
+ items: { type: "string" },
697
+ description: "Phone waterfall order (for set_waterfall)"
698
+ },
699
+ // ─── Status params (absorbed from status tool) ──────────
700
+ check: {
701
+ type: "string",
702
+ enum: ["all", "credits", "health", "config"],
703
+ description: "What to check (for status action): all, credits, health, config"
704
+ },
705
+ provider: {
706
+ type: "string",
707
+ description: "Check a specific provider only (for status action)"
708
+ },
709
+ detail: {
710
+ type: "string",
711
+ enum: ["summary", "full"],
712
+ description: "Response detail level (for status action)"
713
+ }
714
+ },
715
+ required: ["action"]
716
+ }
717
+ }
718
+ ];
719
+
720
+ // src/tools/feedback.ts
721
+ var feedbackTools = [
722
+ {
723
+ name: "feedback",
724
+ description: "Submit feedback, bug reports, feature requests, or provider requests. Use this to report issues with Maestro or request new data providers and capabilities. Feedback is stored for the Maestro maintainers to review.",
725
+ inputSchema: {
726
+ type: "object",
727
+ properties: {
728
+ type: {
729
+ type: "string",
730
+ enum: ["bug", "feature_request", "provider_request"],
731
+ description: 'Type of feedback: "bug" for something broken, "feature_request" for new capabilities, "provider_request" for requesting a new data provider integration'
732
+ },
733
+ message: {
734
+ type: "string",
735
+ description: "Describe the issue, request, or suggestion in detail"
736
+ },
737
+ context: {
738
+ type: "object",
739
+ description: "Optional context \u2014 tool name, error_code, args used, provider, etc. Include anything that helps reproduce or understand the feedback."
740
+ }
741
+ },
742
+ required: ["type", "message"]
743
+ }
744
+ }
745
+ ];
746
+
747
+ // src/tools/review.ts
748
+ var reviewTools = [
749
+ {
750
+ name: "review",
751
+ description: "Push data to a visual review table. Users see an interactive grid in their browser and can select/deselect rows. Use after finding companies or contacts to let the user review before enrichment.",
752
+ inputSchema: {
753
+ type: "object",
754
+ properties: {
755
+ action: {
756
+ type: "string",
757
+ enum: ["create", "update", "get_selected"],
758
+ description: "create: new table from data. update: modify existing table rows. get_selected: fetch user-approved rows."
759
+ },
760
+ title: { type: "string", description: "Table title (for create)" },
761
+ data: {
762
+ type: "array",
763
+ items: { type: "object" },
764
+ description: "Array of row objects (for create)"
765
+ },
766
+ table_id: {
767
+ type: "string",
768
+ description: "Table ID (for update, get_selected, or optional client-provided ID on create)"
769
+ },
770
+ rows: {
771
+ type: "array",
772
+ items: { type: "object" },
773
+ description: "Updated row objects with _row_id (for update)"
774
+ },
775
+ ttl_seconds: {
776
+ type: "number",
777
+ description: "Optional TTL override in seconds (default: 24h). For create only."
778
+ }
779
+ },
780
+ required: ["action"]
781
+ }
782
+ }
783
+ ];
784
+
785
+ // src/tools/batch.ts
786
+ var batchTools = [
787
+ {
788
+ name: "batch",
789
+ description: 'CSV pipeline + saved recipes. Actions: run (default \u2014 process CSV through tool steps), save_recipe, list_recipes, run_recipe, show_recipe, delete_recipe. Always dry_run first to preview. Use rows: "0:1" to pilot on a single row.',
790
+ inputSchema: {
791
+ type: "object",
792
+ properties: {
793
+ input_csv: {
794
+ type: "string",
795
+ description: "Path to input CSV file (supports ~ for home directory)"
796
+ },
797
+ output_csv: {
798
+ type: "string",
799
+ description: "Path for output CSV. Defaults to {input}_enriched.csv"
800
+ },
801
+ steps: {
802
+ type: "array",
803
+ description: "Pipeline steps to run per row",
804
+ items: {
805
+ type: "object",
806
+ properties: {
807
+ alias: {
808
+ type: "string",
809
+ description: 'Column prefix for extracted results (e.g., "enrich" produces "enrich_email")'
810
+ },
811
+ tool: {
812
+ type: "string",
813
+ description: 'GTM tool to call (e.g., "enrich", "find_people")'
814
+ },
815
+ payload_template: {
816
+ type: "object",
817
+ description: "Tool arguments with {{column}} placeholders for row values. Non-string values (numbers, booleans, arrays) pass through as-is."
818
+ },
819
+ extract: {
820
+ type: "array",
821
+ items: { type: "string" },
822
+ description: 'Fields to extract from tool result as new columns. Supports dot-path (e.g., "results.0.email") or simple key lookup.'
823
+ },
824
+ waterfall: {
825
+ type: "boolean",
826
+ description: "Skip this step for a row if all extract fields are already filled by a previous step"
827
+ },
828
+ skip_if: {
829
+ type: "string",
830
+ description: 'JS expression evaluated against `row`. If truthy, skip THIS step. Use after an AI scoring/classification step to conditionally proceed. Example: "Number(row.score_icp_score) < 70" skips personalization for low-score leads.'
831
+ },
832
+ stop_if: {
833
+ type: "string",
834
+ description: "JS expression evaluated against `row`. If truthy, stop ALL remaining steps for this row. Use to filter out unqualified rows early. Example: \"row.classify_fit === 'disqualified'\" stops the entire pipeline for this row."
835
+ }
836
+ },
837
+ required: ["alias", "tool", "payload_template", "extract"]
838
+ }
839
+ },
840
+ rows: {
841
+ type: "string",
842
+ description: 'Row slice as "start:end" (0-indexed, end exclusive). E.g., "0:5" for first 5 rows.'
843
+ },
844
+ dry_run: {
845
+ type: "boolean",
846
+ description: "Preview what would happen without making API calls"
847
+ },
848
+ concurrency: {
849
+ type: "number",
850
+ description: "Worker pool size (1-5, default 1). Processes up to N rows in parallel."
851
+ },
852
+ maestro_strategy: {
853
+ type: "string",
854
+ enum: [
855
+ "call_prep",
856
+ "content_generation",
857
+ "lead_scoring",
858
+ "personalization",
859
+ "campaign_planning",
860
+ "general"
861
+ ],
862
+ description: 'Knowledge graph context strategy. Auto-detected when templates use {{maestro.*}} variables. Injects persona, product, proof point, and competitor data into templates. Default: "personalization".'
863
+ },
864
+ output: {
865
+ type: "object",
866
+ description: 'Route enriched results to a secondary destination (CSV is always written). Types: "review" (interactive review table), "campaign" (push leads), "crm" (create/update contacts).',
867
+ properties: {
868
+ type: {
869
+ type: "string",
870
+ enum: ["review", "campaign", "crm"],
871
+ description: "Output destination type"
872
+ },
873
+ title: {
874
+ type: "string",
875
+ description: 'Review table title (type: "review" only)'
876
+ },
877
+ campaign_id: {
878
+ type: "string",
879
+ description: 'Campaign to push leads to (type: "campaign" only)'
880
+ },
881
+ provider: {
882
+ type: "string",
883
+ description: 'Campaign provider override (type: "campaign" only)'
884
+ },
885
+ lead_mapping: {
886
+ type: "object",
887
+ description: 'Column name mapping for campaign leads: { "email": "enrich_email", "first_name": "name" }. Auto-detected if omitted.'
888
+ },
889
+ action: {
890
+ type: "string",
891
+ enum: ["create", "update"],
892
+ description: 'CRM action (type: "crm" only, default: "create")'
893
+ }
894
+ },
895
+ required: ["type"]
896
+ },
897
+ post_process: {
898
+ type: "string",
899
+ description: 'JS code to run after all rows are processed. Has access to `rows` array. Must return a summary value. Example: "return { qualified: rows.filter(r => Number(r.score_score) >= 70).length }"'
900
+ },
901
+ ai_answers: {
902
+ type: "array",
903
+ description: "Pre-filled AI results from a previous passthrough run. Provide these when re-running a batch after the agent has processed the ai_pending prompts from the first run.",
904
+ items: {
905
+ type: "object",
906
+ properties: {
907
+ row_index: {
908
+ type: "number",
909
+ description: "Row index (0-based) this answer applies to"
910
+ },
911
+ step_alias: { type: "string", description: "Step alias this answer applies to" },
912
+ result: {
913
+ type: "object",
914
+ description: "AI result object with keys matching the step extract fields"
915
+ }
916
+ },
917
+ required: ["row_index", "step_alias", "result"]
918
+ }
919
+ },
920
+ // ─── Recipe params (absorbed from recipe tool) ──────────
921
+ action: {
922
+ type: "string",
923
+ enum: [
924
+ "run",
925
+ "save_recipe",
926
+ "list_recipes",
927
+ "run_recipe",
928
+ "show_recipe",
929
+ "delete_recipe"
930
+ ],
931
+ description: "run (default \u2014 process CSV pipeline), save_recipe, list_recipes, run_recipe, show_recipe, delete_recipe."
932
+ },
933
+ recipe_name: {
934
+ type: "string",
935
+ description: "Recipe name (for save_recipe/run_recipe/show_recipe/delete_recipe)"
936
+ },
937
+ recipe_description: {
938
+ type: "string",
939
+ description: "Recipe description (for save_recipe)"
940
+ },
941
+ config: {
942
+ type: "object",
943
+ description: "Full batch config to save as a recipe (for save_recipe)"
944
+ },
945
+ schedule: {
946
+ type: "string",
947
+ description: "Cron expression for recurring runs (for save_recipe)"
948
+ }
949
+ },
950
+ required: []
951
+ }
952
+ }
953
+ ];
954
+
955
+ // src/tools/recipe.ts
956
+ var recipeTools = [
957
+ {
958
+ name: "recipe",
959
+ description: "Manage reusable batch processing recipes. Save, load, run, and schedule batch pipelines. Recipes are stored as YAML in ~/.gtm/recipes/ and can include schedule expressions for recurring runs.",
960
+ inputSchema: {
961
+ type: "object",
962
+ properties: {
963
+ action: {
964
+ type: "string",
965
+ enum: ["save", "list", "run", "show", "delete"],
966
+ description: "Recipe action to perform"
967
+ },
968
+ name: {
969
+ type: "string",
970
+ description: "Recipe name (required for save, run, show, delete)"
971
+ },
972
+ description: {
973
+ type: "string",
974
+ description: "Recipe description (save only)"
975
+ },
976
+ config: {
977
+ type: "object",
978
+ description: "Full BatchConfig to save as a recipe (save only)"
979
+ },
980
+ schedule: {
981
+ type: "string",
982
+ description: 'Cron expression for recurring runs, e.g., "0 9 * * 1-5" (save only)'
983
+ }
984
+ },
985
+ required: ["action"]
986
+ }
987
+ }
988
+ ];
989
+
990
+ // src/tools/provision.ts
991
+ var provisionTools = [
992
+ {
993
+ name: "provision",
994
+ description: "Infrastructure provisioning \u2014 domain management, mailbox creation, DMARC setup, PlusVibe client creation, config persistence, and full provisioning pipeline.",
995
+ inputSchema: {
996
+ type: "object",
997
+ properties: {
998
+ action: {
999
+ type: "string",
1000
+ enum: [
1001
+ "check_domains",
1002
+ "check_balance",
1003
+ "buy_domains",
1004
+ "list_domains",
1005
+ "list_mailboxes",
1006
+ "setup_dmarc",
1007
+ "create_mailboxes",
1008
+ "export_mailboxes",
1009
+ "create_plusvibe_client",
1010
+ "save_config",
1011
+ "deploy_crm",
1012
+ "start_provision",
1013
+ "status"
1014
+ ],
1015
+ description: "Action: check_domains (availability), check_balance (Zapmail wallet), buy_domains (purchase via wallet), list_domains (show all with status), list_mailboxes (show mailboxes), setup_dmarc (configure DMARC for domains), create_mailboxes (create on specific domains), export_mailboxes (export to PlusVibe), create_plusvibe_client (create client in existing workspace), save_config (persist provider config to ~/.gtm/config.yaml), deploy_crm (generate Twenty CRM deployment instructions for Railway), start_provision (trigger full pipeline), status (check progress)"
1016
+ },
1017
+ domains: {
1018
+ type: "array",
1019
+ items: { type: "string" },
1020
+ description: "Domain names (for check_domains, buy_domains, create_mailboxes)"
1021
+ },
1022
+ domain_ids: {
1023
+ type: "array",
1024
+ items: { type: "string" },
1025
+ description: "Zapmail domain IDs (for setup_dmarc, create_mailboxes)"
1026
+ },
1027
+ mailboxes: {
1028
+ type: "array",
1029
+ items: {
1030
+ type: "object",
1031
+ properties: {
1032
+ username: { type: "string" },
1033
+ firstName: { type: "string" },
1034
+ lastName: { type: "string" }
1035
+ },
1036
+ required: ["username", "firstName", "lastName"]
1037
+ },
1038
+ description: "Mailbox definitions (for create_mailboxes)"
1039
+ },
1040
+ name: {
1041
+ type: "string",
1042
+ description: "Client name (for create_plusvibe_client)"
1043
+ },
1044
+ email: {
1045
+ type: "string",
1046
+ description: "Client email (for create_plusvibe_client, setup_dmarc)"
1047
+ },
1048
+ dmarc_email: {
1049
+ type: "string",
1050
+ description: "DMARC reporting email (for setup_dmarc, defaults to email)"
1051
+ },
1052
+ dmarc_status: {
1053
+ type: "array",
1054
+ items: { type: "string" },
1055
+ description: 'DMARC policy status (for setup_dmarc, defaults to ["p=none"])'
1056
+ },
1057
+ workspace_id: {
1058
+ type: "string",
1059
+ description: "PlusVibe workspace ID (for create_plusvibe_client)"
1060
+ },
1061
+ provider: {
1062
+ type: "string",
1063
+ description: "Provider name (for save_config \u2014 e.g. zapmail, plusvibe, twenty)"
1064
+ },
1065
+ config_values: {
1066
+ type: "object",
1067
+ additionalProperties: { type: "string" },
1068
+ description: 'Config values to save (for save_config \u2014 e.g. {"api_key":"xxx","base_url":"https://..."})'
1069
+ },
1070
+ client_name: {
1071
+ type: "string",
1072
+ description: "Client name in config (for save_config \u2014 defaults to active client)"
1073
+ },
1074
+ client_context: {
1075
+ type: "object",
1076
+ properties: {
1077
+ id: { type: "string" },
1078
+ email: { type: "string" },
1079
+ name: { type: "string" },
1080
+ source: { type: "string", enum: ["student", "dfy_client", "self_serve"] }
1081
+ },
1082
+ required: ["id", "email", "name", "source"],
1083
+ description: "Client identity (required for start_provision)"
1084
+ },
1085
+ provision_id: {
1086
+ type: "string",
1087
+ description: "Provision UUID (for start_provision and status)"
1088
+ },
1089
+ provision_type: {
1090
+ type: "string",
1091
+ enum: ["full", "outreach"],
1092
+ description: "Provision type: full or outreach. Default: full."
1093
+ }
1094
+ },
1095
+ required: ["action"]
1096
+ }
1097
+ }
1098
+ ];
1099
+
1100
+ // src/tools/list.ts
1101
+ var listTools = [
1102
+ {
1103
+ name: "list",
1104
+ description: "Manage persistent GTM lists \u2014 import CSVs, store contacts/companies, query with filters, view in browser. Lists persist in Supabase and can be enriched, scored, and pushed to campaigns incrementally.",
1105
+ inputSchema: {
1106
+ type: "object",
1107
+ properties: {
1108
+ action: {
1109
+ type: "string",
1110
+ description: "Action: create (new list), import_csv (CSV into list), add (items to list), query (filter items), view (open in browser), stats (list summary), lists (show all), delete (remove list)",
1111
+ enum: ["create", "import_csv", "add", "query", "view", "stats", "lists", "delete"]
1112
+ },
1113
+ list_id: {
1114
+ type: "string",
1115
+ description: "List UUID (required for import_csv, add, query, view, stats, delete)"
1116
+ },
1117
+ name: {
1118
+ type: "string",
1119
+ description: "List name (for create)"
1120
+ },
1121
+ description: {
1122
+ type: "string",
1123
+ description: "List description (for create)"
1124
+ },
1125
+ list_type: {
1126
+ type: "string",
1127
+ enum: ["contacts", "companies", "mixed"],
1128
+ description: "List type (for create, default: contacts)"
1129
+ },
1130
+ tags: {
1131
+ type: "array",
1132
+ items: { type: "string" },
1133
+ description: "Tags for filtering (for create, lists)"
1134
+ },
1135
+ client_id: {
1136
+ type: "string",
1137
+ description: "Client scope (for create, lists \u2014 defaults to active client)"
1138
+ },
1139
+ csv_path: {
1140
+ type: "string",
1141
+ description: "Path to CSV file on disk (for import_csv)"
1142
+ },
1143
+ csv_text: {
1144
+ type: "string",
1145
+ description: "Raw CSV text (for import_csv \u2014 alternative to csv_path)"
1146
+ },
1147
+ column_mapping: {
1148
+ type: "object",
1149
+ additionalProperties: { type: "string" },
1150
+ description: 'Override column mapping: {"CSV Column": "core_field"} (for import_csv)'
1151
+ },
1152
+ items: {
1153
+ type: "array",
1154
+ items: {
1155
+ type: "object",
1156
+ properties: {
1157
+ email: { type: "string" },
1158
+ linkedin_url: { type: "string" },
1159
+ first_name: { type: "string" },
1160
+ last_name: { type: "string" },
1161
+ company: { type: "string" },
1162
+ company_domain: { type: "string" },
1163
+ title: { type: "string" },
1164
+ phone: { type: "string" },
1165
+ location: { type: "string" },
1166
+ custom_fields: { type: "object" }
1167
+ }
1168
+ },
1169
+ description: "Contact/company items to add (for add action)"
1170
+ },
1171
+ enrichment_status: {
1172
+ type: "string",
1173
+ enum: ["pending", "enriched", "failed", "skipped"],
1174
+ description: "Filter by enrichment status (for query)"
1175
+ },
1176
+ has_email: {
1177
+ type: "boolean",
1178
+ description: "Filter: has email (for query)"
1179
+ },
1180
+ has_linkedin: {
1181
+ type: "boolean",
1182
+ description: "Filter: has LinkedIn URL (for query)"
1183
+ },
1184
+ search: {
1185
+ type: "string",
1186
+ description: "Text search across name, company, email (for query)"
1187
+ },
1188
+ limit: {
1189
+ type: "number",
1190
+ description: "Max results (for query, default 100)"
1191
+ },
1192
+ offset: {
1193
+ type: "number",
1194
+ description: "Pagination offset (for query)"
1195
+ }
1196
+ },
1197
+ required: ["action"]
1198
+ }
1199
+ }
1200
+ ];
1201
+
1202
+ // src/tools/maestro.ts
1203
+ var maestroTools = [
1204
+ {
1205
+ name: "intel",
1206
+ description: "Knowledge graph \u2014 personas, products, competitors, proof points, scoring, ingestion, and context assembly. Actions: context (strategy-based assembly), product/persona/get_persona/segment/competitor (upsert entities), proof (add evidence), outcome (record deal_won/lost, meeting_booked for learning loop), gaps (missing evidence per persona), score (match contact to personas), propose (AI entity extraction), ingest/ingest_linkedin/refresh_competitor (feed data into graph), changelog (audit trail). Call tool_help for full parameter docs per action.",
1207
+ inputSchema: {
1208
+ type: "object",
1209
+ properties: {
1210
+ action: {
1211
+ type: "string",
1212
+ enum: [
1213
+ "context",
1214
+ "product",
1215
+ "persona",
1216
+ "get_persona",
1217
+ "segment",
1218
+ "proof",
1219
+ "competitor",
1220
+ "outcome",
1221
+ "gaps",
1222
+ "propose",
1223
+ "ingest",
1224
+ "ingest_linkedin",
1225
+ "refresh_competitor",
1226
+ "changelog",
1227
+ "score"
1228
+ ],
1229
+ description: "Context: context (assemble business context by strategy). Entities: product, persona, get_persona, segment, competitor (upsert). Evidence: proof (case studies, testimonials, metrics). Learning: outcome (record GTM outcomes). Analysis: gaps (coverage gaps), score (contact-to-persona matching), propose (AI entity extraction). Ingest: ingest (documents), ingest_linkedin (profile scrape), refresh_competitor (Exa web search). Audit: changelog (mutation history)."
1230
+ },
1231
+ // ─── Context params ─────────────────────────────
1232
+ strategy: {
1233
+ type: "string",
1234
+ enum: [
1235
+ "call_prep",
1236
+ "content_generation",
1237
+ "lead_scoring",
1238
+ "personalization",
1239
+ "campaign_planning",
1240
+ "general"
1241
+ ],
1242
+ description: "Context assembly strategy \u2014 determines entity weights and limits (for context)"
1243
+ },
1244
+ query: {
1245
+ type: "string",
1246
+ description: "Focus context on a topic (for context), or search query (for refresh_competitor)"
1247
+ },
1248
+ // ─── Entity params (shared across multiple actions) ─
1249
+ name: {
1250
+ type: "string",
1251
+ description: "Entity name \u2014 unique per owner (for product/persona/segment/competitor)"
1252
+ },
1253
+ description: {
1254
+ type: "string",
1255
+ description: "Entity description (for product/segment)"
1256
+ },
1257
+ // ─── Product params ─────────────────────────────
1258
+ category: {
1259
+ type: "string",
1260
+ description: "Product category (for product) or proof point category"
1261
+ },
1262
+ value_proposition: {
1263
+ type: "string",
1264
+ description: "Core value proposition (for product)"
1265
+ },
1266
+ key_features: {
1267
+ type: "array",
1268
+ items: { type: "string" },
1269
+ description: "Key features or capabilities (for product)"
1270
+ },
1271
+ pricing_summary: {
1272
+ type: "string",
1273
+ description: "Pricing overview (for product)"
1274
+ },
1275
+ // ─── Persona params ─────────────────────────────
1276
+ persona_id: {
1277
+ type: "string",
1278
+ description: "Persona UUID (for get_persona, context, gaps, proof)"
1279
+ },
1280
+ title_patterns: {
1281
+ type: "array",
1282
+ items: { type: "string" },
1283
+ description: "Job title patterns (for persona)"
1284
+ },
1285
+ industries: {
1286
+ type: "array",
1287
+ items: { type: "string" },
1288
+ description: "Industries (for persona)"
1289
+ },
1290
+ company_size_min: {
1291
+ type: "number",
1292
+ description: "Min company size (for persona)"
1293
+ },
1294
+ company_size_max: {
1295
+ type: "number",
1296
+ description: "Max company size (for persona)"
1297
+ },
1298
+ pain_points: {
1299
+ type: "array",
1300
+ items: { type: "string" },
1301
+ description: "Pain points (for persona)"
1302
+ },
1303
+ goals: {
1304
+ type: "array",
1305
+ items: { type: "string" },
1306
+ description: "Goals (for persona)"
1307
+ },
1308
+ objections: {
1309
+ type: "array",
1310
+ items: { type: "string" },
1311
+ description: "Common objections (for persona)"
1312
+ },
1313
+ buying_signals: {
1314
+ type: "array",
1315
+ items: { type: "string" },
1316
+ description: "Buying intent signals (for persona)"
1317
+ },
1318
+ geographic_focus: {
1319
+ type: "array",
1320
+ items: { type: "string" },
1321
+ description: "Geographic regions (for persona)"
1322
+ },
1323
+ budget_range: {
1324
+ type: "string",
1325
+ description: "Budget range (for persona)"
1326
+ },
1327
+ is_primary: {
1328
+ type: "boolean",
1329
+ description: "Primary persona flag (for persona)"
1330
+ },
1331
+ // ─── Segment params ─────────────────────────────
1332
+ qualification_criteria: {
1333
+ type: "object",
1334
+ description: "Qualification criteria as JSON (for segment)"
1335
+ },
1336
+ market_size_estimate: {
1337
+ type: "string",
1338
+ description: "Estimated market size (for segment)"
1339
+ },
1340
+ // ─── Proof params ───────────────────────────────
1341
+ type: {
1342
+ type: "string",
1343
+ enum: ["case_study", "testimonial", "metric", "quote", "before_after"],
1344
+ description: "Proof point type (for proof)"
1345
+ },
1346
+ title: {
1347
+ type: "string",
1348
+ description: "Short title (for proof)"
1349
+ },
1350
+ content: {
1351
+ type: "string",
1352
+ description: "Full content (for proof, ingest)"
1353
+ },
1354
+ metric_value: {
1355
+ type: "string",
1356
+ description: 'Key metric like "3x ROI" (for proof)'
1357
+ },
1358
+ source_type: {
1359
+ type: "string",
1360
+ description: "Where this came from (for proof, changelog)"
1361
+ },
1362
+ source_id: {
1363
+ type: "string",
1364
+ description: "Source record ID (for proof)"
1365
+ },
1366
+ product_id: {
1367
+ type: "string",
1368
+ description: "Link to product via graph edge (for proof)"
1369
+ },
1370
+ // ─── Competitor params ──────────────────────────
1371
+ website: {
1372
+ type: "string",
1373
+ description: "Competitor website URL (for competitor)"
1374
+ },
1375
+ positioning: {
1376
+ type: "string",
1377
+ description: "Market positioning (for competitor)"
1378
+ },
1379
+ strengths: {
1380
+ type: "array",
1381
+ items: { type: "string" },
1382
+ description: "Competitor strengths (for competitor)"
1383
+ },
1384
+ weaknesses: {
1385
+ type: "array",
1386
+ items: { type: "string" },
1387
+ description: "Competitor weaknesses (for competitor)"
1388
+ },
1389
+ differentiation_notes: {
1390
+ type: "string",
1391
+ description: "How we differentiate (for competitor)"
1392
+ },
1393
+ // ─── Outcome params ─────────────────────────────
1394
+ outcome_type: {
1395
+ type: "string",
1396
+ enum: [
1397
+ "deal_won",
1398
+ "deal_lost",
1399
+ "meeting_booked",
1400
+ "reply_positive",
1401
+ "reply_negative",
1402
+ "content_high_engagement",
1403
+ "content_low_engagement",
1404
+ "campaign_result"
1405
+ ],
1406
+ description: "Outcome type (for outcome)"
1407
+ },
1408
+ entity_type: {
1409
+ type: "string",
1410
+ description: "Graph entity type (for outcome, changelog) \u2014 e.g., persona, product"
1411
+ },
1412
+ entity_id: {
1413
+ type: "string",
1414
+ description: "Entity UUID (for outcome, changelog)"
1415
+ },
1416
+ detail: {
1417
+ type: "string",
1418
+ description: "Outcome description (for outcome)"
1419
+ },
1420
+ metrics: {
1421
+ type: "object",
1422
+ description: "Outcome metrics as JSON (for outcome)"
1423
+ },
1424
+ occurred_at: {
1425
+ type: "string",
1426
+ description: "When the outcome occurred, ISO 8601 (for outcome)"
1427
+ },
1428
+ // ─── Propose params ─────────────────────────────
1429
+ min_entries_per_topic: {
1430
+ type: "number",
1431
+ description: "Min entries per topic to consider, default 3 (for propose)"
1432
+ },
1433
+ max_clusters: {
1434
+ type: "number",
1435
+ description: "Max topic clusters to analyze, default 20 (for propose)"
1436
+ },
1437
+ // ─── Ingest params ──────────────────────────────
1438
+ filename: {
1439
+ type: "string",
1440
+ description: "Document filename (for ingest)"
1441
+ },
1442
+ document_type: {
1443
+ type: "string",
1444
+ enum: [
1445
+ "pitch_deck",
1446
+ "case_study",
1447
+ "icp_doc",
1448
+ "proposal",
1449
+ "sop",
1450
+ "playbook",
1451
+ "competitive_analysis",
1452
+ "other"
1453
+ ],
1454
+ description: "Document type \u2014 determines extraction strategy (for ingest)"
1455
+ },
1456
+ // ─── LinkedIn ingest params ─────────────────────
1457
+ linkedin_url: {
1458
+ type: "string",
1459
+ description: "LinkedIn profile URL (for ingest_linkedin)"
1460
+ },
1461
+ include_posts: {
1462
+ type: "boolean",
1463
+ description: "Also scrape recent posts (for ingest_linkedin)"
1464
+ },
1465
+ // ─── Refresh competitor params ──────────────────
1466
+ competitor_name: {
1467
+ type: "string",
1468
+ description: "Name of competitor to refresh (for refresh_competitor)"
1469
+ },
1470
+ search_query: {
1471
+ type: "string",
1472
+ description: "Custom search query (for refresh_competitor)"
1473
+ },
1474
+ // ─── Changelog params ───────────────────────────
1475
+ source: {
1476
+ type: "string",
1477
+ description: "Filter by change source: manual, ontology_extractor, document_processor, outcome_loop (for changelog)"
1478
+ },
1479
+ limit: {
1480
+ type: "number",
1481
+ description: "Max entries to return (for changelog)"
1482
+ },
1483
+ // ─── Score params ───────────────────────────────
1484
+ headline: {
1485
+ type: "string",
1486
+ description: "LinkedIn headline or job title (for score)"
1487
+ },
1488
+ location: {
1489
+ type: "string",
1490
+ description: "Location (for score)"
1491
+ },
1492
+ company_name: {
1493
+ type: "string",
1494
+ description: "Company name (for score)"
1495
+ },
1496
+ company_size: {
1497
+ type: "string",
1498
+ description: 'Company size range e.g. "11-50" (for score)'
1499
+ },
1500
+ industry: {
1501
+ type: "string",
1502
+ description: "Industry (for score)"
1503
+ },
1504
+ base_score: {
1505
+ type: "number",
1506
+ description: "Base priority score to boost, 0-100 (for score)"
1507
+ },
1508
+ // ─── Ownership (shared) ─────────────────────────
1509
+ owner_id: {
1510
+ type: "string",
1511
+ description: "Owner ID (omit to use your default owner from env)"
1512
+ },
1513
+ owner_type: {
1514
+ type: "string",
1515
+ enum: ["user", "tenant"],
1516
+ description: "Owner type: user or tenant"
1517
+ }
1518
+ },
1519
+ required: ["action"]
1520
+ }
1521
+ }
1522
+ ];
1523
+
1524
+ // src/tools/engagement.ts
1525
+ var engagementTools = [
1526
+ {
1527
+ name: "engagement",
1528
+ description: "Monitor LinkedIn post engagement and auto-send personalized cold emails to engagers. Works with both your own posts AND external posts (competitors, influencers). Enable scraping on any post URL, view engagers, trigger enrichment + PlusVibe push. Enrichment includes email waterfall + phone number lookup. The scrape cron runs every 10 minutes and automatically pushes new engagers through the enrichment waterfall (email + phone finding + validation) and into a PlusVibe campaign.",
1529
+ inputSchema: {
1530
+ type: "object",
1531
+ properties: {
1532
+ action: {
1533
+ type: "string",
1534
+ enum: ["monitor", "status", "engagers", "push"],
1535
+ description: "Action to perform: monitor (enable/disable scraping + cold email on any post), status (show all monitored posts \u2014 own and external), engagers (list engagers for a post), push (configure auto-push on a post \u2014 the scrape cron enriches and pushes every 10 min, or use the returned contacts with gtm_enrich + gtm_campaign for immediate push)"
1536
+ },
1537
+ post_url: {
1538
+ type: "string",
1539
+ description: "LinkedIn post URL. Required for monitor, engagers, and push actions. Works with any LinkedIn post \u2014 your own or external (competitor/influencer)."
1540
+ },
1541
+ enabled: {
1542
+ type: "boolean",
1543
+ description: "Enable (true) or disable (false) engagement scraping. Used with monitor action."
1544
+ },
1545
+ plusvibe_campaign_id: {
1546
+ type: "string",
1547
+ description: "PlusVibe campaign ID to auto-push enriched engagers to. When set with monitor action, all new engagers are automatically enriched and pushed."
1548
+ },
1549
+ opt_in_url: {
1550
+ type: "string",
1551
+ description: "Lead magnet URL for email template {{opt_in_url}} variable. Used with monitor action."
1552
+ },
1553
+ post_topic: {
1554
+ type: "string",
1555
+ description: 'Topic of the post for personalization (e.g. "AI agents", "cold email tips"). Used with monitor action for external posts where we cannot infer the topic.'
1556
+ },
1557
+ creator_name: {
1558
+ type: "string",
1559
+ description: 'Name of the post creator for display purposes (e.g. "Alex Hormozi"). Used with monitor action for external posts.'
1560
+ },
1561
+ filter: {
1562
+ type: "string",
1563
+ enum: ["all", "enriched", "unenriched", "pushed", "unpushed"],
1564
+ description: "Filter engagers by enrichment/push status. Used with engagers action. Default: all."
1565
+ },
1566
+ campaign_id: {
1567
+ type: "string",
1568
+ description: "PlusVibe campaign ID for manual push. Required for push action."
1569
+ },
1570
+ limit: {
1571
+ type: "number",
1572
+ description: "Max number of engagers to return or push. Default: 50."
1573
+ }
1574
+ },
1575
+ required: ["action"]
1576
+ }
1577
+ }
1578
+ ];
1579
+
1580
+ // src/tools/dfy.ts
1581
+ var dfyTools = [
1582
+ {
1583
+ name: "dfy",
1584
+ description: 'Manage DFY (Done-For-You) client engagements. Query engagement status, content output, pipeline progress, and diagnose blockers. Requires SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY. Use action: "list" to see all engagements, "status" for a single engagement, "content" for content items, "pipeline" for the kanban view, "diagnose" to identify blockers, "queue" for items needing attention.',
1585
+ inputSchema: {
1586
+ type: "object",
1587
+ properties: {
1588
+ action: {
1589
+ type: "string",
1590
+ enum: ["list", "status", "content", "pipeline", "diagnose", "queue"],
1591
+ description: "list: all engagements with summary stats (supports name filter). status: single engagement overview (stage, deliverables, intake, blockers). content: content items for an engagement (count, statuses, titles). pipeline: kanban view of all active engagements by stage. diagnose: why is a client stuck? (automation failures, intake quality, blockers). queue: items needing attention (failed, stuck, past-due)."
1592
+ },
1593
+ engagement_id: {
1594
+ type: "string",
1595
+ description: "Engagement ID. Required for status, content, and diagnose actions."
1596
+ },
1597
+ name: {
1598
+ type: "string",
1599
+ description: "Client name or company to search for. Used with list to filter, or with status/content/diagnose as alternative to engagement_id."
1600
+ },
1601
+ status_filter: {
1602
+ type: "string",
1603
+ enum: [
1604
+ "pending_payment",
1605
+ "onboarding",
1606
+ "active",
1607
+ "paused",
1608
+ "completed",
1609
+ "cancelled",
1610
+ "churned"
1611
+ ],
1612
+ description: "Filter engagements by status. Used with list action."
1613
+ },
1614
+ engagement_type: {
1615
+ type: "string",
1616
+ enum: ["intro_offer", "full_dfy"],
1617
+ description: "Filter by engagement type. Used with list action."
1618
+ },
1619
+ tenant_id: {
1620
+ type: "string",
1621
+ description: "Tenant ID override. Defaults to GTM_TENANT_ID env var."
1622
+ }
1623
+ },
1624
+ required: ["action"]
1625
+ }
1626
+ }
1627
+ ];
1628
+
1629
+ // src/tools/tam.ts
1630
+ var tamTools = [
1631
+ {
1632
+ name: "build_tam",
1633
+ description: "Build a Total Addressable Market list by intelligently querying multiple company-finding providers (DiscoLike, Apollo, Exa, StoreLeads, Apify) in budget-optimized sequence. Deduplicates across providers by domain, LinkedIn URL, and company name. Supports session persistence for incremental builds across conversations. Use dry_run to preview provider order and cost estimate without spending credits.",
1634
+ inputSchema: {
1635
+ type: "object",
1636
+ required: ["icp_text"],
1637
+ properties: {
1638
+ icp_text: {
1639
+ type: "string",
1640
+ description: 'Natural language ICP description (e.g., "B2B SaaS startups in US, 50-200 employees, using React")'
1641
+ },
1642
+ domains: {
1643
+ type: "array",
1644
+ items: { type: "string" },
1645
+ description: 'Lookalike seed domains \u2014 find companies similar to these (e.g., ["stripe.com", "plaid.com"])'
1646
+ },
1647
+ budget_usd: {
1648
+ type: "number",
1649
+ description: "Total budget for this TAM build in USD. System allocates across providers and stops when budget is exhausted."
1650
+ },
1651
+ session: {
1652
+ type: "string",
1653
+ description: "Session name to resume or create (persists to ~/.gtm/tam-sessions/). Resuming a session deduplicates against all previously found companies."
1654
+ },
1655
+ providers: {
1656
+ type: "array",
1657
+ items: { type: "string" },
1658
+ description: 'Override automatic provider order (e.g., ["disco", "apollo"]). Default: auto-routed based on ICP analysis.'
1659
+ },
1660
+ max_per_provider: {
1661
+ type: "number",
1662
+ description: "Max companies to fetch per provider (default: 500)"
1663
+ },
1664
+ limit: {
1665
+ type: "number",
1666
+ description: "Total target companies across all providers (default: 1000)"
1667
+ },
1668
+ country: {
1669
+ type: "string",
1670
+ description: 'Country filter (e.g., "US", "UK", "DE")'
1671
+ },
1672
+ min_employees: {
1673
+ type: "number",
1674
+ description: "Minimum employee count"
1675
+ },
1676
+ max_employees: {
1677
+ type: "number",
1678
+ description: "Maximum employee count"
1679
+ },
1680
+ tech_stack: {
1681
+ type: "array",
1682
+ items: { type: "string" },
1683
+ description: 'Filter by technology stack (e.g., ["React", "AWS"])'
1684
+ },
1685
+ category: {
1686
+ type: "string",
1687
+ description: 'Industry category filter (e.g., "SaaS", "FinTech", "Healthcare")'
1688
+ },
1689
+ negate_domains: {
1690
+ type: "array",
1691
+ items: { type: "string" },
1692
+ description: "Domains to always exclude from results (e.g., your own company)"
1693
+ },
1694
+ output: {
1695
+ type: "string",
1696
+ enum: ["summary", "file", "inline"],
1697
+ description: "Output mode. summary (default): round stats + file path. file: full JSONL/CSV output. inline: all companies in response (auto-switches to file if >200)."
1698
+ },
1699
+ dry_run: {
1700
+ type: "boolean",
1701
+ description: "Preview provider routing order and cost estimate without executing any API calls"
1702
+ }
1703
+ }
1704
+ }
1705
+ }
1706
+ ];
1707
+
1708
+ // src/tools/knowledge.ts
1709
+ var knowledgeTools = [
1710
+ {
1711
+ name: "knowledge",
1712
+ description: "AI Brain \u2014 search, browse, ask questions, submit transcripts. Actions: search (query), browse, clusters, ask (question), submit (transcript + title).",
1713
+ inputSchema: {
1714
+ type: "object",
1715
+ properties: {
1716
+ action: {
1717
+ type: "string",
1718
+ enum: ["search", "browse", "clusters", "ask", "submit"],
1719
+ description: "search (semantic), browse (by category), clusters (topic themes), ask (AI Q&A), submit (ingest transcript)"
1720
+ },
1721
+ query: { type: "string", description: "Search query (for search action)" },
1722
+ question: { type: "string", description: "Question to answer (for ask action)" },
1723
+ transcript: {
1724
+ type: "string",
1725
+ description: "Transcript text to ingest (for submit action, min 100 chars)"
1726
+ },
1727
+ title: { type: "string", description: "Transcript title (for submit action)" },
1728
+ category: {
1729
+ type: "string",
1730
+ enum: ["insight", "question", "product_intel"],
1731
+ description: "Filter by category"
1732
+ },
1733
+ type: {
1734
+ type: "string",
1735
+ description: "Filter by type: how_to, insight, story, question, objection, mistake, decision, market_intel"
1736
+ },
1737
+ tag: { type: "string", description: "Filter by tag (for browse action)" },
1738
+ min_quality: {
1739
+ type: "number",
1740
+ description: "Minimum quality score 1-5 (for search)"
1741
+ },
1742
+ limit: { type: "number", description: "Max results (default 20)" },
1743
+ team_id: { type: "string", description: "Team ID (optional, for multi-team)" }
1744
+ },
1745
+ required: ["action"]
1746
+ }
1747
+ }
1748
+ ];
1749
+
1750
+ // src/tools/mixer.ts
1751
+ var mixerTools = [
1752
+ {
1753
+ name: "mixer",
1754
+ description: "Generate content by combining ingredients: exploits (formats), knowledge entries, styles, templates, creatives, and trends. Returns draft posts or ideas. Actions: mix (generate), inventory (available ingredients), recipes (suggested combos), performance (historical metrics).",
1755
+ inputSchema: {
1756
+ type: "object",
1757
+ properties: {
1758
+ action: {
1759
+ type: "string",
1760
+ enum: ["mix", "inventory", "recipes", "performance"],
1761
+ description: "mix (generate content), inventory (available ingredients), recipes (suggested combos), performance (historical metrics)"
1762
+ },
1763
+ team_profile_id: {
1764
+ type: "string",
1765
+ description: "Team profile ID (required for all actions)"
1766
+ },
1767
+ exploit_id: { type: "string", description: "Exploit/format to use (for mix)" },
1768
+ knowledge_topic: {
1769
+ type: "string",
1770
+ description: "Knowledge topic to incorporate (for mix)"
1771
+ },
1772
+ knowledge_query: {
1773
+ type: "string",
1774
+ description: "Search knowledge by query (for mix)"
1775
+ },
1776
+ style_id: { type: "string", description: "Writing style to apply (for mix)" },
1777
+ template_id: { type: "string", description: "Template to follow (for mix)" },
1778
+ creative_id: {
1779
+ type: "string",
1780
+ description: "Creative/swipe file to reference (for mix)"
1781
+ },
1782
+ trend_topic: {
1783
+ type: "string",
1784
+ description: "Trending topic to incorporate (for mix)"
1785
+ },
1786
+ hook: { type: "string", description: "Custom hook/opening (for mix)" },
1787
+ instructions: {
1788
+ type: "string",
1789
+ description: "Additional generation instructions (for mix)"
1790
+ },
1791
+ count: {
1792
+ type: "number",
1793
+ description: "Number of outputs (default 3, for mix)"
1794
+ },
1795
+ output: {
1796
+ type: "string",
1797
+ enum: ["drafts", "ideas"],
1798
+ description: "Output type (default drafts, for mix)"
1799
+ },
1800
+ limit: {
1801
+ type: "number",
1802
+ description: "Max results (for recipes/performance)"
1803
+ }
1804
+ },
1805
+ required: ["action"]
1806
+ }
1807
+ }
1808
+ ];
1809
+
1810
+ // src/tools/dm-coach.ts
1811
+ var dmCoachTools = [
1812
+ {
1813
+ name: "dm",
1814
+ description: "AI coaching for LinkedIn DM conversations. Get suggested responses based on conversation history, qualification stage, and goal. Actions: suggest (AI coaching), list/get/create/update/delete (manage contacts), messages (add conversation messages).",
1815
+ inputSchema: {
1816
+ type: "object",
1817
+ properties: {
1818
+ action: {
1819
+ type: "string",
1820
+ enum: ["suggest", "list", "get", "create", "update", "delete", "messages"],
1821
+ description: "suggest (AI coaching), list/get/create/update/delete (manage contacts), messages (add conversation messages)"
1822
+ },
1823
+ id: {
1824
+ type: "string",
1825
+ description: "Contact ID (required for suggest, get, update, delete, messages)"
1826
+ },
1827
+ name: { type: "string", description: "Contact name (for create)" },
1828
+ linkedin_url: { type: "string", description: "LinkedIn URL (for create)" },
1829
+ headline: { type: "string", description: "Contact headline (for create/update)" },
1830
+ company: { type: "string", description: "Contact company (for create/update)" },
1831
+ conversation_goal: {
1832
+ type: "string",
1833
+ enum: [
1834
+ "book_meeting",
1835
+ "build_relationship",
1836
+ "promote_content",
1837
+ "explore_partnership",
1838
+ "nurture_lead",
1839
+ "close_deal"
1840
+ ],
1841
+ description: "Conversation goal (for create/update)"
1842
+ },
1843
+ status: {
1844
+ type: "string",
1845
+ enum: ["active", "paused", "closed_won", "closed_lost"],
1846
+ description: "Filter by status (for list) or set status (for update)"
1847
+ },
1848
+ messages: {
1849
+ type: "array",
1850
+ items: {
1851
+ type: "object",
1852
+ properties: {
1853
+ role: { type: "string", enum: ["them", "me"] },
1854
+ content: { type: "string" },
1855
+ timestamp: { type: "string", description: "ISO 8601 timestamp" }
1856
+ },
1857
+ required: ["role", "content"]
1858
+ },
1859
+ description: "Messages to add (for messages action)"
1860
+ },
1861
+ notes: { type: "string", description: "Contact notes (for create/update)" },
1862
+ search: { type: "string", description: "Search by name (for list)" },
1863
+ team_id: { type: "string", description: "Team ID (optional, for multi-team)" }
1864
+ },
1865
+ required: ["action"]
1866
+ }
1867
+ }
1868
+ ];
1869
+
1870
+ // src/tools/launch.ts
1871
+ var launchTools = [
1872
+ {
1873
+ name: "launch",
1874
+ description: "Multi-step shortcuts. Actions: magnet (create magnet + funnel + email + publish in one call), schedule_week (batch-create + schedule posts).",
1875
+ inputSchema: {
1876
+ type: "object",
1877
+ properties: {
1878
+ action: {
1879
+ type: "string",
1880
+ enum: ["magnet", "schedule_week"],
1881
+ description: "magnet (create + publish lead magnet end-to-end), schedule_week (batch create + schedule posts)"
1882
+ },
1883
+ title: {
1884
+ type: "string",
1885
+ description: "Lead magnet title (for magnet action)"
1886
+ },
1887
+ archetype: {
1888
+ type: "string",
1889
+ enum: [
1890
+ "single-breakdown",
1891
+ "single-system",
1892
+ "focused-toolkit",
1893
+ "single-calculator",
1894
+ "focused-directory",
1895
+ "mini-training",
1896
+ "one-story",
1897
+ "prompt",
1898
+ "assessment",
1899
+ "workflow"
1900
+ ],
1901
+ description: "Lead magnet archetype (for magnet action)"
1902
+ },
1903
+ content: {
1904
+ type: "object",
1905
+ description: "Lead magnet content matching archetype schema (for magnet action)"
1906
+ },
1907
+ slug: {
1908
+ type: "string",
1909
+ description: "Funnel page slug (for magnet action)"
1910
+ },
1911
+ funnel_theme: {
1912
+ type: "string",
1913
+ enum: ["dark", "light", "modern"],
1914
+ description: "Funnel visual theme (for magnet action)"
1915
+ },
1916
+ email_sequence: {
1917
+ type: "object",
1918
+ description: "Email sequence config: { emails: [{ day, subject, body }] } (for magnet action)"
1919
+ },
1920
+ posts: {
1921
+ type: "array",
1922
+ items: {
1923
+ type: "object",
1924
+ properties: {
1925
+ body: { type: "string" },
1926
+ title: { type: "string" },
1927
+ pillar: { type: "string" },
1928
+ content_type: { type: "string" }
1929
+ },
1930
+ required: ["body"]
1931
+ },
1932
+ description: "Posts to create and schedule (for schedule_week action)"
1933
+ },
1934
+ week_start: {
1935
+ type: "string",
1936
+ description: "ISO date for start of week (defaults next Monday, for schedule_week)"
1937
+ },
1938
+ team_id: { type: "string", description: "Team ID (optional)" }
1939
+ },
1940
+ required: ["action"]
1941
+ }
1942
+ }
1943
+ ];
1944
+
1945
+ // src/tools/exploit.ts
1946
+ var exploitTools = [
1947
+ {
1948
+ name: "exploit",
1949
+ description: "Use proven LinkedIn post formats (exploits) to generate content. List available formats, generate a post from a format + knowledge + style combination, or see trending topics.",
1950
+ inputSchema: {
1951
+ type: "object",
1952
+ properties: {
1953
+ action: {
1954
+ type: "string",
1955
+ enum: ["list", "generate", "trends"],
1956
+ description: "list (available formats), generate (create post from format), trends (trending topics)"
1957
+ },
1958
+ category: {
1959
+ type: "string",
1960
+ enum: ["regular_post", "lead_magnet"],
1961
+ description: "Filter exploits by category (for list)"
1962
+ },
1963
+ with_stats: {
1964
+ type: "boolean",
1965
+ description: "Include engagement stats (for list)"
1966
+ },
1967
+ exploit_id: {
1968
+ type: "string",
1969
+ description: "Exploit/format ID to use (for generate)"
1970
+ },
1971
+ creative_id: {
1972
+ type: "string",
1973
+ description: "Creative swipe file to reference (for generate)"
1974
+ },
1975
+ knowledge_ids: {
1976
+ type: "array",
1977
+ items: { type: "string" },
1978
+ description: "Knowledge entry IDs to incorporate (for generate)"
1979
+ },
1980
+ template_id: { type: "string", description: "Template ID (for generate)" },
1981
+ style_id: { type: "string", description: "Writing style ID (for generate)" },
1982
+ hook: {
1983
+ type: "string",
1984
+ description: "Custom hook/opening line (for generate)"
1985
+ },
1986
+ instructions: {
1987
+ type: "string",
1988
+ description: "Additional instructions (for generate)"
1989
+ },
1990
+ limit: {
1991
+ type: "number",
1992
+ description: "Max results (for trends, default 10)"
1993
+ }
1994
+ },
1995
+ required: ["action"]
1996
+ }
1997
+ }
1998
+ ];
1999
+
2000
+ // src/tools/mode.ts
2001
+ var modeTools = [
2002
+ {
2003
+ name: "switch_mode",
2004
+ description: "Switch the active tool profile to show only relevant tools. Profiles: core (~20 general-purpose tools), discover (company/people search + TAM), create (content + knowledge tools), campaign (outreach + email), intel (knowledge graph \u2014 15 tools), manage (CRM + admin), full (all tools). Switching replaces the current profile. All tools remain callable regardless of profile.",
2005
+ inputSchema: {
2006
+ type: "object",
2007
+ required: ["profile"],
2008
+ properties: {
2009
+ profile: {
2010
+ type: "string",
2011
+ enum: ["core", "discover", "create", "campaign", "intel", "manage", "full"],
2012
+ description: "Profile to switch to"
2013
+ },
2014
+ show: {
2015
+ type: "boolean",
2016
+ description: "If true, show current profile and available profiles without switching"
2017
+ }
2018
+ }
2019
+ }
2020
+ }
2021
+ ];
2022
+
2023
+ // src/tools/magnet.ts
2024
+ var magnetTools = [
2025
+ {
2026
+ name: "magnet",
2027
+ description: "Lead magnet lifecycle: CRUD, email sequences, and launch shortcut. CRUD: list, get, create (title + archetype required), update, delete. Sequences: get_sequence, save_sequence, activate_sequence (day-relative drip emails). Shortcuts: launch (create magnet + funnel + sequence + publish in one call), schedule_week (batch create + schedule posts).",
2028
+ inputSchema: {
2029
+ type: "object",
2030
+ properties: {
2031
+ action: {
2032
+ type: "string",
2033
+ enum: [
2034
+ "list",
2035
+ "get",
2036
+ "create",
2037
+ "update",
2038
+ "delete",
2039
+ "publish",
2040
+ "get_sequence",
2041
+ "save_sequence",
2042
+ "activate_sequence",
2043
+ "launch",
2044
+ "schedule_week"
2045
+ ],
2046
+ description: "CRUD: list, get, create, update, delete. Publishing: publish (set status to published, requires id). Sequences: get_sequence, save_sequence, activate_sequence. Shortcuts: launch (all-in-one), schedule_week (batch posts)."
2047
+ },
2048
+ id: {
2049
+ type: "string",
2050
+ description: "Lead magnet ID (for get/update/delete/sequence actions)"
2051
+ },
2052
+ title: { type: "string", description: "Lead magnet title (for create/launch)" },
2053
+ archetype: {
2054
+ type: "string",
2055
+ enum: [
2056
+ "single-breakdown",
2057
+ "single-system",
2058
+ "focused-toolkit",
2059
+ "single-calculator",
2060
+ "focused-directory",
2061
+ "mini-training",
2062
+ "one-story",
2063
+ "prompt",
2064
+ "assessment",
2065
+ "workflow"
2066
+ ],
2067
+ description: "Lead magnet archetype (for create/launch). Determines content schema."
2068
+ },
2069
+ content: {
2070
+ type: "object",
2071
+ description: "Lead magnet content matching archetype schema (for update/launch)"
2072
+ },
2073
+ status: {
2074
+ type: "string",
2075
+ enum: ["draft", "published", "archived"],
2076
+ description: "Filter by status (for list)"
2077
+ },
2078
+ limit: { type: "number", description: "Max results (for list)" },
2079
+ offset: { type: "number", description: "Pagination offset (for list)" },
2080
+ // ─── Sequence params (absorbed from email_sequence) ─────
2081
+ emails: {
2082
+ type: "array",
2083
+ items: {
2084
+ type: "object",
2085
+ properties: {
2086
+ day: { type: "number", description: "Day number in sequence" },
2087
+ subject: { type: "string", description: "Email subject line" },
2088
+ body: { type: "string", description: "Email body (HTML or plain text)" }
2089
+ },
2090
+ required: ["day", "subject", "body"]
2091
+ },
2092
+ description: "Email sequence entries (for save_sequence)"
2093
+ },
2094
+ // ─── Launch params (absorbed from launch) ───────────────
2095
+ slug: { type: "string", description: "Funnel page slug (for launch)" },
2096
+ funnel_theme: {
2097
+ type: "string",
2098
+ enum: ["dark", "light", "modern"],
2099
+ description: "Funnel visual theme (for launch)"
2100
+ },
2101
+ email_sequence: {
2102
+ type: "object",
2103
+ description: "Email sequence config: { emails: [{ day, subject, body }] } (for launch)"
2104
+ },
2105
+ // ─── Schedule week params (absorbed from launch) ────────
2106
+ posts: {
2107
+ type: "array",
2108
+ items: {
2109
+ type: "object",
2110
+ properties: {
2111
+ body: { type: "string" },
2112
+ title: { type: "string" },
2113
+ pillar: { type: "string" },
2114
+ content_type: { type: "string" }
2115
+ },
2116
+ required: ["body"]
2117
+ },
2118
+ description: "Posts to create and schedule (for schedule_week)"
2119
+ },
2120
+ week_start: {
2121
+ type: "string",
2122
+ description: "ISO date for start of week (for schedule_week)"
2123
+ },
2124
+ team_id: { type: "string", description: "Team ID (omit to use your default team)" }
2125
+ },
2126
+ required: ["action"]
2127
+ }
2128
+ }
2129
+ ];
2130
+
2131
+ // src/tools/funnel.ts
2132
+ var funnelTools = [
2133
+ {
2134
+ name: "funnel",
2135
+ description: "Opt-in funnel pages for lead magnets. CRUD: list, get, create (lead_magnet_id required), update, delete. Publishing: publish, unpublish. Update supports: optinSubline, optinSocialProof, thankyouSubline, qualificationFormId, vslUrl, calendlyUrl, qualificationPassMessage, qualificationFailMessage. Qualification forms: list_forms, get_form (form_id), get_questions (form_id).",
2136
+ inputSchema: {
2137
+ type: "object",
2138
+ properties: {
2139
+ action: {
2140
+ type: "string",
2141
+ enum: [
2142
+ "list",
2143
+ "get",
2144
+ "create",
2145
+ "update",
2146
+ "delete",
2147
+ "publish",
2148
+ "unpublish",
2149
+ "list_forms",
2150
+ "get_form",
2151
+ "get_questions"
2152
+ ],
2153
+ description: "CRUD: list, get, create, update, delete. Publishing: publish, unpublish. Qualification forms: list_forms, get_form (form_id required), get_questions (form_id required)."
2154
+ },
2155
+ id: { type: "string", description: "Funnel ID (for get/update/delete/publish/unpublish)" },
2156
+ lead_magnet_id: {
2157
+ type: "string",
2158
+ description: "Lead magnet to create funnel for (for create)"
2159
+ },
2160
+ theme: {
2161
+ type: "string",
2162
+ enum: ["dark", "light", "modern"],
2163
+ description: "Visual theme (for create/update)"
2164
+ },
2165
+ content: {
2166
+ type: "object",
2167
+ description: "Funnel page content (for update)"
2168
+ },
2169
+ // ─── Updatable funnel fields (for update) ─────────────
2170
+ optinSubline: { type: "string", description: "Opt-in page subtitle text (for update)" },
2171
+ optinSocialProof: {
2172
+ type: "string",
2173
+ description: "Social proof text on opt-in page (for update)"
2174
+ },
2175
+ thankyouSubline: {
2176
+ type: "string",
2177
+ description: "Thank you page subtitle text (for update)"
2178
+ },
2179
+ qualificationFormId: {
2180
+ type: "string",
2181
+ description: "Qualification form ID to attach (for update)"
2182
+ },
2183
+ vslUrl: { type: "string", description: "Video sales letter URL (for update)" },
2184
+ calendlyUrl: { type: "string", description: "Booking calendar URL (for update)" },
2185
+ qualificationPassMessage: {
2186
+ type: "string",
2187
+ description: "Message shown when lead qualifies (for update)"
2188
+ },
2189
+ qualificationFailMessage: {
2190
+ type: "string",
2191
+ description: "Message shown when lead fails qualification (for update)"
2192
+ },
2193
+ // ─── Qualification form params ────────────────────────
2194
+ form_id: {
2195
+ type: "string",
2196
+ description: "Qualification form ID (for get_form, get_questions)"
2197
+ },
2198
+ team_id: { type: "string", description: "Team ID (omit to use your default team)" }
2199
+ },
2200
+ required: ["action"]
2201
+ }
2202
+ }
2203
+ ];
2204
+
2205
+ // src/tools/post.ts
2206
+ var postTools = [
2207
+ {
2208
+ name: "post",
2209
+ description: "LinkedIn posts \u2014 CRUD, AI generation, content queue, and discovery. Actions: list/get/create/update/delete, publish/publish_linkedin/list_accounts, generate, queue_list/queue_update/queue_submit, formats/ingredients/recipes/trends/performance. Call tool_help for generation params.",
2210
+ inputSchema: {
2211
+ type: "object",
2212
+ properties: {
2213
+ action: {
2214
+ type: "string",
2215
+ enum: [
2216
+ "list",
2217
+ "get",
2218
+ "create",
2219
+ "update",
2220
+ "delete",
2221
+ "publish",
2222
+ "publish_linkedin",
2223
+ "list_accounts",
2224
+ "generate",
2225
+ "queue_list",
2226
+ "queue_update",
2227
+ "queue_submit",
2228
+ "formats",
2229
+ "ingredients",
2230
+ "recipes",
2231
+ "trends",
2232
+ "performance"
2233
+ ],
2234
+ description: "CRUD: list, get, create, update, delete. Publish: publish (schedule), publish_linkedin (post now), list_accounts. Generate: generate (AI content). Discovery: formats, ingredients, recipes, trends, performance."
2235
+ },
2236
+ // ─── CRUD params ─────────────────────────────
2237
+ id: { type: "string", description: "Post ID (for get/update/delete/publish)" },
2238
+ body: { type: "string", description: "Post body text (for create/update)" },
2239
+ title: { type: "string", description: "Post title (for create/update)" },
2240
+ pillar: { type: "string", description: "Content pillar (for create)" },
2241
+ content_type: { type: "string", description: "Content type (for create)" },
2242
+ status: { type: "string", description: "Filter by status (for list)" },
2243
+ limit: { type: "number", description: "Max results (for list/recipes/trends/performance)" },
2244
+ offset: { type: "number", description: "Pagination offset (for list)" },
2245
+ // ─── Publish params ──────────────────────────
2246
+ account_id: {
2247
+ type: "string",
2248
+ description: "LinkedIn account to publish to (for publish_linkedin)"
2249
+ },
2250
+ // ─── Generation params (from mixer) ──────────
2251
+ exploit_id: { type: "string", description: "Post format/exploit to use (for generate)" },
2252
+ knowledge_topic: {
2253
+ type: "string",
2254
+ description: "Knowledge topic to incorporate (for generate)"
2255
+ },
2256
+ knowledge_query: {
2257
+ type: "string",
2258
+ description: "Search knowledge by query (for generate)"
2259
+ },
2260
+ knowledge_ids: {
2261
+ type: "array",
2262
+ items: { type: "string" },
2263
+ description: "Knowledge entry IDs to incorporate (for generate)"
2264
+ },
2265
+ style_id: { type: "string", description: "Writing style to apply (for generate)" },
2266
+ template_id: { type: "string", description: "Template to follow (for generate)" },
2267
+ creative_id: {
2268
+ type: "string",
2269
+ description: "Creative/swipe file to reference (for generate)"
2270
+ },
2271
+ trend_topic: {
2272
+ type: "string",
2273
+ description: "Trending topic to incorporate (for generate)"
2274
+ },
2275
+ hook: { type: "string", description: "Custom hook/opening (for generate)" },
2276
+ instructions: {
2277
+ type: "string",
2278
+ description: "Additional generation instructions (for generate)"
2279
+ },
2280
+ count: {
2281
+ type: "number",
2282
+ description: "Number of outputs to generate (default 3, for generate)"
2283
+ },
2284
+ output: {
2285
+ type: "string",
2286
+ enum: ["drafts", "ideas"],
2287
+ description: "Output type (default drafts, for generate)"
2288
+ },
2289
+ // ─── Formats params (from exploit) ───────────
2290
+ category: {
2291
+ type: "string",
2292
+ enum: ["regular_post", "lead_magnet"],
2293
+ description: "Filter formats by category (for formats)"
2294
+ },
2295
+ with_stats: {
2296
+ type: "boolean",
2297
+ description: "Include engagement stats (for formats)"
2298
+ },
2299
+ team_id: { type: "string", description: "Team ID (omit to use your default team)" }
2300
+ },
2301
+ required: ["action"]
2302
+ }
2303
+ }
2304
+ ];
2305
+
2306
+ // src/tools/email-sequence.ts
2307
+ var emailSequenceTools = [
2308
+ {
2309
+ name: "email_sequence",
2310
+ description: "Email nurture drip for lead magnets. Actions: get \u2192 save \u2192 activate. Requires lead_magnet_id.",
2311
+ inputSchema: {
2312
+ type: "object",
2313
+ properties: {
2314
+ action: {
2315
+ type: "string",
2316
+ enum: ["get", "save", "activate"],
2317
+ description: "get (view), save (create/update), activate (start sending)"
2318
+ },
2319
+ lead_magnet_id: {
2320
+ type: "string",
2321
+ description: "Lead magnet ID (required for all actions)"
2322
+ },
2323
+ emails: {
2324
+ type: "array",
2325
+ items: {
2326
+ type: "object",
2327
+ properties: {
2328
+ day: { type: "number", description: "Day number in sequence" },
2329
+ subject: { type: "string", description: "Email subject line" },
2330
+ body: { type: "string", description: "Email body (HTML or plain text)" }
2331
+ },
2332
+ required: ["day", "subject", "body"]
2333
+ },
2334
+ description: "Email sequence entries (for save action)"
2335
+ },
2336
+ team_id: { type: "string", description: "Team ID (omit to use your default team)" }
2337
+ },
2338
+ required: ["action", "lead_magnet_id"]
2339
+ }
2340
+ }
2341
+ ];
2342
+
2343
+ // src/tools/leads.ts
2344
+ var leadsTools = [
2345
+ {
2346
+ name: "leads",
2347
+ description: "View/export leads captured via funnel opt-ins. Actions: list, get, export (csv/json).",
2348
+ inputSchema: {
2349
+ type: "object",
2350
+ properties: {
2351
+ action: {
2352
+ type: "string",
2353
+ enum: ["list", "get", "export"],
2354
+ description: "list (browse leads), get (single lead), export (download)"
2355
+ },
2356
+ id: { type: "string", description: "Lead ID (for get)" },
2357
+ lead_magnet_id: { type: "string", description: "Filter by lead magnet (for list)" },
2358
+ status: { type: "string", description: "Filter by status (for list)" },
2359
+ limit: { type: "number", description: "Max results (for list, default 50)" },
2360
+ offset: { type: "number", description: "Pagination offset (for list)" },
2361
+ format: {
2362
+ type: "string",
2363
+ enum: ["csv", "json"],
2364
+ description: "Export format (for export, default csv)"
2365
+ },
2366
+ team_id: { type: "string", description: "Team ID (omit to use your default team)" }
2367
+ },
2368
+ required: ["action"]
2369
+ }
2370
+ }
2371
+ ];
2372
+
2373
+ // src/tools/analytics.ts
2374
+ var analyticsTools = [
2375
+ {
2376
+ name: "analytics",
2377
+ description: "Team-wide GTM performance insights and AI recommendations. Actions: insights, recommendations.",
2378
+ inputSchema: {
2379
+ type: "object",
2380
+ properties: {
2381
+ action: {
2382
+ type: "string",
2383
+ enum: ["insights", "recommendations"],
2384
+ description: "insights (performance metrics), recommendations (AI suggestions)"
2385
+ },
2386
+ team_id: { type: "string", description: "Team ID (omit to use your default team)" }
2387
+ },
2388
+ required: ["action"]
2389
+ }
2390
+ }
2391
+ ];
2392
+
2393
+ // src/tools/outreach.ts
2394
+ var outreachTools = [
2395
+ {
2396
+ name: "outreach",
2397
+ description: "App-managed LinkedIn outreach campaigns with safety gates and human-like timing. Actions: list, get, create, update, activate, pause, delete, add_leads. Different from campaign: these are Maestro-managed sequences, not provider-level ops.",
2398
+ inputSchema: {
2399
+ type: "object",
2400
+ properties: {
2401
+ action: {
2402
+ type: "string",
2403
+ enum: ["list", "get", "create", "update", "activate", "pause", "delete", "add_leads"],
2404
+ description: "list, get, create, update, activate, pause, delete, add_leads."
2405
+ },
2406
+ id: {
2407
+ type: "string",
2408
+ description: "Outreach campaign ID (for get/update/activate/pause/delete/add_leads)"
2409
+ },
2410
+ name: { type: "string", description: "Campaign name (for create/update)" },
2411
+ message_template: {
2412
+ type: "string",
2413
+ description: "Message template with {{placeholders}} (for create/update)"
2414
+ },
2415
+ follow_up_template: {
2416
+ type: "string",
2417
+ description: "Follow-up message template (for create/update)"
2418
+ },
2419
+ follow_up_delay_days: {
2420
+ type: "number",
2421
+ description: "Days before follow-up (for create/update)"
2422
+ },
2423
+ leads: {
2424
+ type: "array",
2425
+ items: {
2426
+ type: "object",
2427
+ properties: {
2428
+ linkedin_url: { type: "string", description: "LinkedIn profile URL (required)" },
2429
+ first_name: { type: "string" },
2430
+ last_name: { type: "string" },
2431
+ company: { type: "string" },
2432
+ headline: { type: "string" }
2433
+ },
2434
+ required: ["linkedin_url"]
2435
+ },
2436
+ description: "Leads to add (for add_leads)"
2437
+ },
2438
+ team_id: { type: "string", description: "Team ID (omit to use your default team)" }
2439
+ },
2440
+ required: ["action"]
2441
+ }
2442
+ }
2443
+ ];
2444
+
2445
+ // src/tools/creative.ts
2446
+ var creativeTools = [
2447
+ {
2448
+ name: "creative",
2449
+ description: 'Swipe file management for content generation. Actions: list (browse saved creatives), create (add a new creative), scan (analyze creatives for performance patterns), configure_sources (set up auto-scan sources). Creatives feed into post({ action: "generate", creative_id: "..." }).',
2450
+ inputSchema: {
2451
+ type: "object",
2452
+ properties: {
2453
+ action: {
2454
+ type: "string",
2455
+ enum: ["list", "create", "scan", "configure_sources"],
2456
+ description: "list, create, scan, configure_sources."
2457
+ },
2458
+ url: { type: "string", description: "URL of creative to add (for create)" },
2459
+ body: { type: "string", description: "Creative content body (for create, if not URL)" },
2460
+ source: { type: "string", description: "Source attribution (for create)" },
2461
+ tags: {
2462
+ type: "array",
2463
+ items: { type: "string" },
2464
+ description: "Tags for categorization (for create)"
2465
+ },
2466
+ sources: {
2467
+ type: "array",
2468
+ items: {
2469
+ type: "object",
2470
+ properties: {
2471
+ type: { type: "string", description: "Source type (linkedin_profile, rss, etc.)" },
2472
+ url: { type: "string", description: "Source URL" }
2473
+ },
2474
+ required: ["type", "url"]
2475
+ },
2476
+ description: "Scanner sources to configure (for configure_sources)"
2477
+ },
2478
+ limit: { type: "number", description: "Max results (for list)" },
2479
+ team_id: { type: "string", description: "Team ID (omit to use your default team)" }
2480
+ },
2481
+ required: ["action"]
2482
+ }
2483
+ }
2484
+ ];
2485
+
2486
+ // src/tools/safety.ts
2487
+ var safetyTools = [
2488
+ {
2489
+ name: "safety",
2490
+ description: "Account safety settings for LinkedIn. Actions: get (view current limits), update (change limits). Manage daily action limits, cool-down periods, and risk thresholds.",
2491
+ inputSchema: {
2492
+ type: "object",
2493
+ properties: {
2494
+ action: {
2495
+ type: "string",
2496
+ enum: ["get", "update"],
2497
+ description: "get (view settings), update (change settings)."
2498
+ },
2499
+ account_id: { type: "string", description: "LinkedIn account ID (required)" },
2500
+ daily_connection_limit: {
2501
+ type: "number",
2502
+ description: "Max connection requests per day (for update)"
2503
+ },
2504
+ daily_message_limit: { type: "number", description: "Max messages per day (for update)" },
2505
+ daily_view_limit: { type: "number", description: "Max profile views per day (for update)" },
2506
+ cooldown_minutes: { type: "number", description: "Minutes between actions (for update)" },
2507
+ risk_level: {
2508
+ type: "string",
2509
+ enum: ["conservative", "moderate", "aggressive"],
2510
+ description: "Risk threshold preset (for update)"
2511
+ },
2512
+ team_id: { type: "string", description: "Team ID (omit to use your default team)" }
2513
+ },
2514
+ required: ["action", "account_id"]
2515
+ }
2516
+ }
2517
+ ];
2518
+
2519
+ // src/tools/descriptions.ts
2520
+ var TOOL_DESCRIPTIONS = {
2521
+ find_companies: `Discover companies matching your ICP criteria. Powered by DiscoLike (60M+ companies from web/SSL crawl data) and optionally Apollo.
2522
+
2523
+ DiscoLike strengths:
2524
+ - Lookalike discovery: give it 1-10 seed domains, get similar companies
2525
+ - ICP text matching: describe your ideal customer in plain English
2526
+ - Tech stack filtering: find companies using specific technologies
2527
+ - Website content analysis: matches against actual site content
2528
+ - Best for: B2B companies, local businesses, professional services, healthcare
2529
+
2530
+ For DTC/e-commerce brands, use provider: "storeleads" \u2014 it has revenue estimates and category data that neither DiscoLike nor Apollo provides.
2531
+
2532
+ Tip: DiscoLike lookalike mode is extremely powerful. If you have 2-3 example companies, use the domains parameter to find hundreds of similar ones.
2533
+
2534
+ Single domain lookup: passing just domain (no icp_text, domains, category, tech_stack, or country) does a direct company profile fetch with rich data (growth signals, engagement metrics, tech stack from vendors). This is for researching ONE specific company, not discovery.
2535
+
2536
+ Pass review: true to push discovery results to a visual review table at view.maestrogtm.com so the user can select companies before enrichment or outreach.
2537
+
2538
+ Exa (provider: "exa") \u2014 semantic/neural search:
2539
+ - Meaning-based ICP matching: "B2B SaaS companies selling to healthcare, not healthtech vendors" actually works
2540
+ - Best for: nuanced ICP descriptions where keyword matching fails
2541
+ - Uses icp_text for semantic search, domains for lookalike discovery
2542
+ - Does NOT return employee count, industry, or tech stack \u2014 use for discovery, then enrich with DiscoLike or Apollo
2543
+ - Must be explicitly selected with provider: "exa" (not auto-selected)
2544
+ - Requires GTM_EXA_API_KEY env var`,
2545
+ find_people: `Find contacts at companies by job title, company, or domain. Returns name, title, email (when available), phone, and LinkedIn URL.
2546
+
2547
+ Powered by DiscoLike Contacts, Apollo, or BetterContact depending on configuration.
2548
+
2549
+ DiscoLike strengths:
2550
+ - Domain-based search: pass company_domain or company_domains[] for multi-domain batch
2551
+ - Seniority filtering (owner, founder, c_suite, partner, vp, head, director, manager, senior, entry, intern)
2552
+ - Industry + skills filtering to narrow results without post-processing
2553
+ - email_validated flag for pre-verified emails only
2554
+ - Employee/revenue range filters for company-level targeting
2555
+ - Returns validated emails when available
2556
+
2557
+ Response is slim by default (name, title, email, company, company_domain, linkedin). Pass fields: "all" for full payload.
2558
+
2559
+ After finding people, use:
2560
+ - enrich to get verified email/phone if not returned (company_domain field is pipeline-compatible)
2561
+ - extract to check LinkedIn activity and engagement signals
2562
+
2563
+ Known limitations:
2564
+ - department + seniority filters combined may return 0 results (Disco API uses strict AND). Use one or the other.
2565
+
2566
+ Pass review: true to push results to a visual review table at view.maestrogtm.com so the user can select rows before proceeding.`,
2567
+ enrich: `Email/phone waterfall enrichment + single-email verification.
2568
+
2569
+ Actions: (default) waterfall enrichment, verify (single email deliverability check).
2570
+
2571
+ ENRICHMENT: Tries multiple providers in order, stops on first match. Supports 1-100 contacts per call. IMPORTANT: Defaults to email only. Phone enrichment costs extra \u2014 only include when user explicitly asks. Always dry_run first for batches > 5.
2572
+
2573
+ Providers (in configured waterfall order):
2574
+ - Prospeo: email finder, good hit rate on LinkedIn-active professionals
2575
+ - BetterContact: email + phone, charges only on successful find
2576
+
2577
+ Input needs: first_name + last_name minimum. Adding company_domain dramatically improves hit rates. LinkedIn URL is the gold standard input.
2578
+
2579
+ Pass table_id to read contacts from an existing review table (selected rows only). Pass review: true to push enrichment results to a new review table.
2580
+
2581
+ VERIFY: Pass action: "verify" + email to check deliverability. Returns: deliverable, catch_all_safe, catch_all_not_safe, undeliverable, or unknown. Use after enrichment or to validate an existing email.`,
2582
+ verify: 'Verify a single email address for deliverability. Absorbed into enrich({ action: "verify" }).',
2583
+ extract: `Extract structured data from any URL or platform. LinkedIn profiles, posts, engagement, search results, company posts, and web pages.
2584
+
2585
+ When to use:
2586
+ - Scrape a LinkedIn profile for headline, experience, skills, follower count
2587
+ - Check if someone is active on LinkedIn (recent posts, engagement levels)
2588
+ - Find people who comment on or react to specific posts (warm lead mining)
2589
+ - Search LinkedIn posts by keyword to find thought leaders
2590
+ - Monitor competitor or industry content for engagers
2591
+ - Scrape any web page for structured data
2592
+
2593
+ When NOT to use:
2594
+ - Finding people by job title at a company \u2014 use find_people instead
2595
+ - Email enrichment \u2014 use enrich instead
2596
+
2597
+ Pairs well with:
2598
+ - find_people \u2192 extract (find contacts, then check LinkedIn activity)
2599
+ - extract linkedin_engagement \u2192 enrich (find engagers, then get emails)
2600
+ - storeleads \u2192 find_people \u2192 extract (DTC brands \u2192 CEOs \u2192 activity check)
2601
+
2602
+ Note: HarvestAPI charges per request. For engagement mining, each post lookup counts as a request. Use limit to control costs.`,
2603
+ fetch: "Make an HTTP call to any API endpoint. Use this to pull data from services that don't have a dedicated provider.",
2604
+ ai: "AI-powered data operations: personalize outreach, classify leads, clean data, score prospects, or write copy. Provide an action, input data, and optional prompt. Uses your configured AI provider (Anthropic or OpenAI).",
2605
+ campaign: "Manage cold email + LinkedIn outreach campaigns AND engagement monitoring. Campaign actions: list, stats, add_leads, create. Supports PlusVibe, Instantly, Smartlead (email) and HeyReach (LinkedIn). Each lead must have at least one of email or linkedin_url. Pass table_id to read leads directly from a review table. Engagement actions: monitor (enable/disable LinkedIn post scraping + set PlusVibe campaign), engagement_status (show all monitored posts with counts), engagers (list engagers for a post with enrichment/push status), push (trigger enrichment + PlusVibe push for unpushed engagers). Works with YOUR posts and ANY external post (competitors, influencers). Engagers are enriched via email waterfall + phone lookup and pushed with engagement context variables (post_topic, engagement_type, comment_text).",
2606
+ engagement: 'Monitor LinkedIn post engagement and auto-push to cold email campaigns. Absorbed into campaign({ action: "monitor|engagement_status|engagers|push" }).',
2607
+ crm: "Read and write CRM data. Find, create, or update people and companies. Create deals. Supports Attio and other CRM providers. For the create action, pass table_id to bulk-create contacts from a review table (selected rows only).",
2608
+ status: 'Check provider health, credit balances, and active configuration. Absorbed into configure({ action: "status" }).',
2609
+ configure: 'System config + provider health. Config actions: switch_client, list_clients, show_config, set_waterfall, add_client. Status action: status (provider health, credits, capabilities \u2014 shows which providers are configured and their remaining credits). Use action: "status" to check all provider health, or pass provider param for a single provider check.',
2610
+ guide: "CALL THIS FIRST before any multi-step GTM task. Returns step-by-step workflow recipes for common tasks like building a TAM list, running enrichment, launching cold outreach, or coaching LinkedIn DM replies with Kondo. Always check the guide before starting work to ensure you follow the correct sequence and avoid wasting credits.",
2611
+ tool_help: "Get the full parameter schema for a specific GTM tool. Use this to see exactly what arguments a tool accepts before calling execute.",
2612
+ execute: "Gateway to execute any GTM tool by name. Use guide for workflow recipes, tool_help for parameter schemas, then this to execute.",
2613
+ feedback: "Submit feedback, bug reports, feature requests, or provider requests. Feedback is stored for the Maestro maintainers to review.",
2614
+ review: "Push data to a visual review table hosted at view.maestrogtm.com. Users see an interactive AG Grid in their browser with checkboxes to select/deselect rows. Creates a temporary table (24h TTL) with a shareable URL. Use after finding companies or contacts to let the user review before spending enrichment credits. Three actions: create (new table from data array), update (modify existing table \u2014 add columns, update rows), get_selected (fetch only the rows the user has checked).",
2615
+ batch: 'CSV pipeline + saved recipes. Pipeline actions: run (default \u2014 process CSV through tool steps). Each row runs through steps sequentially \u2014 results extracted as new columns. Use rows: "0:1" to pilot on a single row, dry_run: true to preview without API calls. Template placeholders ({{column}}) for row values. Waterfall mode: set waterfall: true on later steps to skip rows already filled by earlier steps. Recipe actions: save_recipe (persist a batch config under a name), list_recipes, run_recipe (re-run saved config), show_recipe, delete_recipe. Recipes capture full pipeline configs for repeatable execution without re-specifying steps.',
2616
+ provision: "Infrastructure provisioning for client setup. Thirteen actions: check_domains (Zapmail domain availability), check_balance (Zapmail wallet), buy_domains (purchase via wallet), list_domains (all domains with status), list_mailboxes (mailboxes for a domain), setup_dmarc (DMARC for domain IDs), create_mailboxes (mailboxes on domains), export_mailboxes (export to PlusVibe/Instantly), create_plusvibe_client (client in existing workspace), save_config (persist provider config), deploy_crm (Twenty CRM deployment instructions for Railway), start_provision (trigger full provisioning pipeline via gtm-api), status (check provisioning progress).",
2617
+ recipe: "Save, list, run, show, and delete reusable batch pipeline recipes. A recipe captures a full batch config (steps, waterfall, output routing) under a name so it can be re-run later without re-specifying the pipeline. Use save to persist a batch config, list to see saved recipes, show to inspect one, run to execute it, and delete to remove it.",
2618
+ build_tam: "Build a Total Addressable Market list by intelligently querying multiple company-finding providers (DiscoLike, Apollo, Exa, StoreLeads, Apify) in budget-optimized sequence. Deduplicates across providers by domain, LinkedIn URL, and company name. Supports session persistence for incremental builds across conversations. Use dry_run to preview provider order and cost estimate without spending credits.",
2619
+ list: "Persistent GTM list management. Create named lists, import CSVs with auto-detected columns, add contacts, query with filters, view in browser via interactive AG Grid table. Lists persist in Supabase and support incremental enrichment, persona scoring, and campaign push. Custom columns preserved in custom_fields. Use import_csv to bring in Clay exports or any CSV. Use view to open the list in the gtm-viewer browser app.",
2620
+ manage_list: "Persistent GTM list management. Renamed to list \u2014 use list() instead.",
2621
+ // ─── DFY (Done-For-You) ────────────────────────────────
2622
+ dfy: "Manage DFY (Done-For-You) client engagements \u2014 query status, content output, pipeline progress, and diagnose blockers. Actions: list (all engagements with summary stats, supports name filter), status (single engagement overview with deliverables and stage info), content (content items count, statuses, titles for an engagement), pipeline (kanban view of all active engagements grouped by stage), diagnose (identify why a client is stuck \u2014 checks intake quality, automation failures, blocked dependencies), queue (items needing attention \u2014 failed automations, stuck deliverables, past-due items). Supports name-based lookup: pass name instead of engagement_id to search by client name or company.",
2623
+ // ─── Intel (Knowledge Graph) ───────────────────────────
2624
+ intel: "Knowledge graph \u2014 the business intelligence layer. 15 actions covering entity CRUD, context assembly, scoring, ingestion, and auditing.\n\nCONTEXT: context (strategy-based assembly \u2014 call_prep, content_generation, lead_scoring, personalization, campaign_planning, general). Each strategy tunes which entities are included and their priority.\n\nENTITIES: product (what the business sells \u2014 upserts by name), persona (buyer profiles with title patterns, pain points, buying signals \u2014 upserts by name), get_persona (get one or the primary persona), segment (market categories broader than personas), competitor (positioning, strengths, weaknesses).\n\nEVIDENCE: proof (case studies, testimonials, metrics, quotes, before/after \u2014 optionally linked to persona/product via graph edges).\n\nLEARNING: outcome (record deal_won/lost, meeting_booked, reply_positive/negative, content engagement, campaign_result \u2014 feeds the learning loop).\n\nANALYSIS: gaps (coverage gaps per persona \u2014 missing proof points, competitive blind spots), score (match any contact against graph personas \u2014 returns best match, confidence, priority boost), propose (AI extracts entity candidates from knowledge entries \u2014 human review required).\n\nINGEST: ingest (documents \u2014 pitch decks, case studies, ICP docs, proposals, SOPs, playbooks), ingest_linkedin (scrape LinkedIn profile via HarvestAPI + classify against graph), refresh_competitor (Exa web search \u2192 update competitor record).\n\nAUDIT: changelog (mutation history with source, reason, diff).",
2625
+ // ─── Product Tools ──────────────────────────────────────
2626
+ magnet: "Lead magnet lifecycle: CRUD, email sequences, and launch shortcut. CRUD: list, get, create (title + archetype required), update, delete. Archetypes: single-breakdown, single-system, focused-toolkit, single-calculator, focused-directory, mini-training, one-story, prompt, assessment, workflow. Sequences: get_sequence, save_sequence, activate_sequence (day-relative drip emails attached to a magnet). Email day numbers are relative to lead signup (day 0 = immediate). Shortcuts: launch (create magnet + funnel + sequence + publish in one call \u2014 requires title + archetype + content), schedule_week (batch create + schedule posts \u2014 requires posts array with body, optional week_start). After creating, use funnel for opt-in page \u2192 leads for captured contacts.",
2627
+ funnel: "Manage opt-in funnel pages for lead magnets. Each funnel is a landing page connected to exactly one lead magnet \u2014 create the magnet first. Create with lead_magnet_id + theme (dark/light/modern). Publish to make it live at its URL, unpublish to take offline. Leads who opt in via the funnel are visible in the leads tool.",
2628
+ post: "Unified content tool for LinkedIn posts. CRUD: list/get/create (body required)/update/delete. Publishing: publish (add to content queue for scheduled posting), publish_linkedin (post immediately \u2014 requires account_id from list_accounts). AI Generation: generate (requires at least one of exploit_id, knowledge_topic, knowledge_query, trend_topic, or instructions). Queue: queue_list (view queue), queue_update (modify scheduled post), queue_submit (submit queue for publishing). Discovery: formats (proven post structures), ingredients (available content pieces), recipes (AI-suggested combos), trends (hot topics), performance (historical engagement metrics for past posts).",
2629
+ email_sequence: "Manage email nurture sequences attached to lead magnets. Create the magnet first. Workflow: get \u2192 save \u2192 activate. Email day numbers are relative to lead signup (day 0 = immediate, day 1 = next day). Once activated, new leads from the magnet's funnel automatically receive the drip sequence.",
2630
+ leads: "View and export leads captured through lead magnet funnels \u2014 people who opted in via a funnel page. List with filters (lead_magnet_id, status). Export as CSV or JSON. Note: these are opt-in leads, not prospecting contacts (use find_people for outbound prospecting).",
2631
+ analytics: "Team-wide performance insights and AI-powered recommendations across all GTM activities (magnets, funnels, posts, campaigns). Two actions: insights (aggregate metrics overview) and recommendations (AI-generated improvement suggestions). For individual post engagement metrics, use post with action: performance instead.",
2632
+ // ─── App Content Tools ────────────────────────────────
2633
+ knowledge: "Search, browse, or ask questions against the AI knowledge base (Brain). search (pass query param) finds entries by semantic meaning. ask (pass question param) uses RAG to synthesize an answer with citations. browse lists recent entries by category/type/tag. clusters shows topic groupings. submit ingests call transcripts or meeting notes (pass transcript + title).",
2634
+ mixer: "Generate LinkedIn content by combining ingredients: exploits (proven post formats), knowledge entries, writing styles, templates, and creatives (swipe file). Returns draft posts or ideas. Use inventory to see available ingredients, recipes for AI-suggested combinations, and performance for historical engagement data.",
2635
+ dm: "AI-coached LinkedIn DM conversations. Add conversation messages (theirs and yours), then get AI-suggested responses based on conversation history, qualification stage (SPIN framework), and conversation goal (book meeting, build relationship, close deal, etc.). Uses Acknowledge-Value-Question framework + SPIN ladder.",
2636
+ dm_coach: "AI-coached LinkedIn DM conversations. Renamed to dm \u2014 use dm() instead.",
2637
+ launch: 'All-in-one shortcuts for multi-step content creation. "magnet" creates lead magnet + opt-in funnel + email sequence + publishes in one atomic call (requires title + archetype + content). Use magnet/funnel/email_sequence tools individually for more control. "schedule_week" batch-creates posts and schedules across the week (requires posts array with body, optional week_start defaults to next Monday).',
2638
+ exploit: "Use proven LinkedIn post formats (exploits) to generate high-engagement content. List shows available formats with optional engagement stats. Generate creates a post from a format combined with knowledge entries, styles, and templates. Trends shows what topics are currently performing well.",
2639
+ outreach: "App-managed LinkedIn outreach campaigns with built-in safety gates and human-like timing. Actions: list, get, create, update, activate, pause, delete, add_leads. Different from campaign: these are Maestro-managed sequences. For provider-level campaign ops (PlusVibe stats, HeyReach push), use campaign instead.",
2640
+ creative: 'Swipe file management for content generation. Actions: list (browse saved creatives), create (add a new creative by URL or body text), scan (analyze creatives for performance patterns), configure_sources (set up auto-scan sources like LinkedIn profiles, RSS feeds). Creatives feed into post({ action: "generate", creative_id: "..." }) for AI content generation.',
2641
+ safety: "Account safety settings for LinkedIn. Actions: get (view current limits for an account), update (change limits). Manage daily action limits (connections, messages, profile views), cool-down periods between actions, and risk level presets (conservative, moderate, aggressive).",
2642
+ switch_mode: "Switch the active tool profile to control which tools appear in MCP listTools. Profiles group tools by workflow: core (~20 general-purpose), discover (company/people search + TAM), create (content + knowledge), campaign (outreach + email), intel (knowledge graph + knowledge), manage (CRM + admin), full (all tools). Pass show: true to see current profile without switching. All tools remain callable via callTool regardless of active profile."
2643
+ };
2644
+
2645
+ // src/tools/catalog.ts
2646
+ var CATEGORY_LABELS = {
2647
+ prospect: "Discovery & Prospecting",
2648
+ enrich: "Enrichment & Verification",
2649
+ extract: "Data Extraction",
2650
+ fetch: "HTTP Requests",
2651
+ ai: "AI Operations",
2652
+ campaign: "Email Campaigns",
2653
+ crm: "CRM Operations",
2654
+ status: "Provider Status",
2655
+ configure: "Configuration",
2656
+ batch: "Batch Processing",
2657
+ recipe: "Recipes",
2658
+ provision: "Domain Provisioning",
2659
+ list: "List Management",
2660
+ maestro: "Intelligence & Scoring",
2661
+ engagement: "Engagement Monitoring",
2662
+ dfy: "DFY Client Management",
2663
+ tam: "TAM Discovery",
2664
+ knowledge: "Knowledge Base",
2665
+ mixer: "Content Mixing",
2666
+ dm_coach: "DM Coaching",
2667
+ launch: "Compound Actions",
2668
+ exploit: "Content Formats",
2669
+ mode: "Tool Profiles",
2670
+ magnet: "Lead Magnets",
2671
+ funnel: "Funnel Pages",
2672
+ post: "LinkedIn Posts",
2673
+ email_sequence: "Email Sequences",
2674
+ leads: "Lead Management",
2675
+ analytics: "Analytics",
2676
+ meta: "Meta-Tools"
2677
+ };
2678
+ function buildCatalogText(exclude) {
2679
+ const lines = [];
2680
+ for (const [category, toolNames] of Object.entries(toolCategories)) {
2681
+ const filtered = toolNames.filter((n) => !exclude?.has(n));
2682
+ if (!filtered.length) continue;
2683
+ const label = CATEGORY_LABELS[category] || category;
2684
+ lines.push(`
2685
+ ### ${label}`);
2686
+ for (const name of filtered) {
2687
+ const tool = toolsByName.get(name);
2688
+ const desc = tool?.description?.split("\n")[0] || "";
2689
+ lines.push(` ${name} \u2014 ${desc.slice(0, 120)}`);
2690
+ }
2691
+ }
2692
+ return lines.join("\n");
2693
+ }
2694
+
2695
+ // src/tools/index.ts
2696
+ var capabilityTools = [
2697
+ ...prospectTools,
2698
+ ...enrichTools,
2699
+ ...extractTools,
2700
+ ...fetchTools,
2701
+ ...aiTools,
2702
+ ...campaignTools,
2703
+ ...crmTools,
2704
+ ...statusTools,
2705
+ ...configureTools,
2706
+ ...feedbackTools,
2707
+ ...reviewTools,
2708
+ ...batchTools,
2709
+ ...recipeTools,
2710
+ ...provisionTools,
2711
+ ...listTools,
2712
+ ...maestroTools,
2713
+ ...engagementTools,
2714
+ ...dfyTools,
2715
+ ...tamTools,
2716
+ ...knowledgeTools,
2717
+ ...mixerTools,
2718
+ ...dmCoachTools,
2719
+ ...launchTools,
2720
+ ...exploitTools,
2721
+ ...modeTools,
2722
+ ...magnetTools,
2723
+ ...funnelTools,
2724
+ ...postTools,
2725
+ ...emailSequenceTools,
2726
+ ...leadsTools,
2727
+ ...analyticsTools,
2728
+ ...outreachTools,
2729
+ ...creativeTools,
2730
+ ...safetyTools
2731
+ ];
2732
+ var guideTool = {
2733
+ name: "guide",
2734
+ description: 'Step-by-step workflow recipes for multi-step GTM tasks. Call with task: "list_tasks" to see all available workflows.',
2735
+ inputSchema: {
2736
+ type: "object",
2737
+ properties: {
2738
+ task: {
2739
+ type: "string",
2740
+ enum: [
2741
+ "build_tam",
2742
+ "enrich_list",
2743
+ "cold_outreach",
2744
+ "linkedin_outreach",
2745
+ "crm_sync",
2746
+ "export_to_webhook",
2747
+ "engagement_cold_email",
2748
+ "create_magnet",
2749
+ "content_pipeline",
2750
+ "dm_coaching",
2751
+ "qualify_inbox",
2752
+ "list_tasks"
2753
+ ],
2754
+ description: "The workflow to get guidance for"
2755
+ }
2756
+ },
2757
+ required: ["task"]
2758
+ }
2759
+ };
2760
+ var toolHelpTool = {
2761
+ name: "tool_help",
2762
+ description: "Get parameter schema for a GTM tool, or operational playbook for a provider. Use before calling tools to see accepted arguments and provider-specific quirks.",
2763
+ inputSchema: {
2764
+ type: "object",
2765
+ properties: {
2766
+ tool: {
2767
+ type: "string",
2768
+ description: 'The tool name to get help for (e.g., "enrich", "find_companies")'
2769
+ },
2770
+ provider: {
2771
+ type: "string",
2772
+ description: 'Provider name to get operational playbook (quirks, cost, best practices). E.g., "apollo", "prospeo", "attio"'
2773
+ },
2774
+ topic: {
2775
+ type: "string",
2776
+ enum: ["waterfall_ordering", "csv_best_practices"],
2777
+ description: "Get workflow pattern guidance instead of tool/provider help"
2778
+ }
2779
+ }
2780
+ }
2781
+ };
2782
+ var executeTool = {
2783
+ name: "execute",
2784
+ description: "Gateway to execute any GTM tool by name. Use guide for workflow recipes, tool_help for parameter schemas, then this to execute.",
2785
+ inputSchema: {
2786
+ type: "object",
2787
+ properties: {
2788
+ tool: {
2789
+ type: "string",
2790
+ description: 'The tool name to execute (e.g., "enrich")'
2791
+ },
2792
+ arguments: {
2793
+ type: "object",
2794
+ description: "The arguments to pass to the tool, matching its schema"
2795
+ }
2796
+ },
2797
+ required: ["tool"]
2798
+ }
2799
+ };
2800
+ var metaTools = [guideTool, toolHelpTool, executeTool];
2801
+ var tools = [...capabilityTools, ...metaTools];
2802
+ var MCP_HIDDEN_TOOLS = /* @__PURE__ */ new Set([
2803
+ "execute",
2804
+ "mixer",
2805
+ "exploit",
2806
+ // Absorbed tools (Phase 2):
2807
+ "verify",
2808
+ // → enrich({ action: 'verify' })
2809
+ "engagement",
2810
+ // → campaign({ action: 'monitor|engagement_status|engagers|push' })
2811
+ "status",
2812
+ // → configure({ action: 'status' })
2813
+ "recipe",
2814
+ // → batch({ action: 'save_recipe|list_recipes|...' })
2815
+ "email_sequence",
2816
+ // → magnet({ action: 'get_sequence|save_sequence|activate_sequence' })
2817
+ "launch",
2818
+ // → magnet({ action: 'launch|schedule_week' })
2819
+ "feedback",
2820
+ // Dropped from MCP — not agent-critical
2821
+ // Renamed tools (Phase 4):
2822
+ "manage_list",
2823
+ // → list
2824
+ "dm_coach"
2825
+ // → dm
2826
+ ]);
2827
+ var mcpTools = tools.filter((t) => !MCP_HIDDEN_TOOLS.has(t.name));
2828
+ var toolsByName = new Map(tools.map((tool) => [tool.name, tool]));
2829
+ var toolCategories = {
2830
+ prospect: prospectTools.map((t) => t.name),
2831
+ enrich: enrichTools.map((t) => t.name),
2832
+ extract: extractTools.map((t) => t.name),
2833
+ fetch: fetchTools.map((t) => t.name),
2834
+ ai: aiTools.map((t) => t.name),
2835
+ campaign: campaignTools.map((t) => t.name),
2836
+ crm: crmTools.map((t) => t.name),
2837
+ status: statusTools.map((t) => t.name),
2838
+ configure: configureTools.map((t) => t.name),
2839
+ batch: batchTools.map((t) => t.name),
2840
+ recipe: recipeTools.map((t) => t.name),
2841
+ provision: provisionTools.map((t) => t.name),
2842
+ list: listTools.map((t) => t.name),
2843
+ maestro: maestroTools.map((t) => t.name),
2844
+ engagement: engagementTools.map((t) => t.name),
2845
+ dfy: dfyTools.map((t) => t.name),
2846
+ tam: tamTools.map((t) => t.name),
2847
+ knowledge: knowledgeTools.map((t) => t.name),
2848
+ mixer: mixerTools.map((t) => t.name),
2849
+ dm_coach: dmCoachTools.map((t) => t.name),
2850
+ launch: launchTools.map((t) => t.name),
2851
+ exploit: exploitTools.map((t) => t.name),
2852
+ mode: modeTools.map((t) => t.name),
2853
+ magnet: magnetTools.map((t) => t.name),
2854
+ funnel: funnelTools.map((t) => t.name),
2855
+ post: postTools.map((t) => t.name),
2856
+ email_sequence: emailSequenceTools.map((t) => t.name),
2857
+ leads: leadsTools.map((t) => t.name),
2858
+ analytics: analyticsTools.map((t) => t.name),
2859
+ meta: metaTools.map((t) => t.name)
2860
+ };
2861
+ var workflowRecipes = {
2862
+ build_tam: `# Build a TAM List \u2014 Workflow
2863
+
2864
+ Start by identifying what kind of companies you're targeting:
2865
+
2866
+ ## DTC / E-commerce / Consumer Brands
2867
+ 1. find_companies (provider: storeleads) \u2014 filter by category, revenue, country
2868
+ \u2192 find_companies({ provider: "storeleads", category: "Beauty", min_revenue: 1000000, country: "US" })
2869
+ 2. find_people \u2014 find decision-makers at those domains
2870
+ \u2192 find_people({ company_domain: "...", job_title: "CEO" })
2871
+ 3. enrich (dry_run first) \u2014 get verified emails
2872
+ \u2192 enrich({ contacts: [...], find: ["email"], dry_run: true })
2873
+ 4. Optional: extract \u2014 check if they're active on LinkedIn
2874
+ \u2192 extract({ type: "linkedin_profile", linkedin_url: "..." })
2875
+
2876
+ ## B2B / SaaS / Services with websites
2877
+ 1. find_companies \u2014 use DiscoLike ICP text or lookalikes
2878
+ \u2192 find_companies({ icp_text: "...", limit: 100 })
2879
+ 2. find_people \u2014 find contacts by title
2880
+ 3. enrich \u2014 get verified emails
2881
+ 4. campaign \u2014 push to email or LinkedIn campaigns
2882
+
2883
+ ## LinkedIn-native prospects
2884
+ 1. find_people \u2014 search by title + company
2885
+ 2. extract \u2014 scrape profiles for activity signals
2886
+ \u2192 extract({ type: "linkedin_profile", linkedin_url: "..." })
2887
+ 3. enrich \u2014 get emails for active prospects
2888
+ 4. campaign \u2014 push to LinkedIn or email campaign
2889
+
2890
+ ## Engagement-based (warm leads)
2891
+ 1. extract (linkedin_search) \u2014 find relevant content
2892
+ \u2192 extract({ type: "linkedin_search", query: "...", sort: "date" })
2893
+ 2. extract (linkedin_engagement) \u2014 extract commenters/reactors
2894
+ \u2192 extract({ type: "linkedin_engagement", post_url: "...", engagement_type: "both" })
2895
+ 3. enrich \u2014 get emails
2896
+ 4. campaign \u2014 personalized outreach referencing their engagement
2897
+
2898
+ ## Review before enriching
2899
+ After finding companies, review the list before spending enrichment credits:
2900
+ - Use output: 'csv' to write results to a spreadsheet for visual review
2901
+ - Or export to Clay/webhook via fetch POST for team review (see export_to_webhook guide)
2902
+ - Use ai with action: 'classify' to auto-filter competitors or bad fits
2903
+
2904
+ ## Key principle
2905
+ Always dry_run enrichment first. Credits are spent per successful find \u2014 previewing cost avoids surprises.`,
2906
+ enrich_list: `# Enrich a Contact List \u2014 Workflow
2907
+
2908
+ ## Steps
2909
+
2910
+ 1. PREPARE \u2014 Ensure contacts have at minimum first_name + last_name. company or company_domain dramatically improves match rates.
2911
+
2912
+ 2. DRY RUN \u2014 Preview cost before spending credits
2913
+ \u2192 enrich({ contacts: [...], find: ["email"], dry_run: true })
2914
+
2915
+ 3. EXECUTE \u2014 Run the waterfall enrichment
2916
+ \u2192 enrich({ contacts: [...], find: ["email"], verify: true })
2917
+
2918
+ 4. REVIEW \u2014 Check results. The waterfall tries each provider in order and stops on first match.
2919
+
2920
+ ## Waterfall order
2921
+ Default order comes from your config. Override per-call with the waterfall parameter.
2922
+ Most providers charge only on successful find \u2014 no result, no charge.`,
2923
+ cold_outreach: `# Cold Email Outreach \u2014 Workflow
2924
+
2925
+ ## Steps
2926
+
2927
+ 1. ENRICH \u2014 Get verified emails for your contacts
2928
+ \u2192 enrich({ contacts: [...], find: ["email"], verify: true, dry_run: true })
2929
+ \u2192 enrich({ contacts: [...], find: ["email"], verify: true })
2930
+
2931
+ 2. PERSONALIZE \u2014 Use AI to write custom openers
2932
+ \u2192 ai({ action: "personalize", data: [...], prompt: "Write a 2-sentence cold email opener referencing their company" })
2933
+
2934
+ 3. LIST CAMPAIGNS \u2014 Find or identify the target campaign
2935
+ \u2192 campaign({ action: "list" })
2936
+
2937
+ 4. PUSH \u2014 Add enriched + personalized leads to campaign
2938
+ \u2192 campaign({ action: "add_leads", campaign_id: "...", leads: [...] })
2939
+
2940
+ 5. SYNC CRM \u2014 Create contacts in CRM for tracking
2941
+ \u2192 crm({ action: "create", data: { first_name: "...", last_name: "...", email: "..." } })
2942
+
2943
+ ## Key principle
2944
+ Always verify emails before pushing to campaigns. Bounced emails hurt sender reputation.`,
2945
+ linkedin_outreach: `# LinkedIn Outreach \u2014 Workflow
2946
+
2947
+ ## Steps
2948
+
2949
+ 1. EXTRACT \u2014 Get LinkedIn profile data
2950
+ \u2192 extract({ url: "https://linkedin.com/in/...", type: "linkedin_profile" })
2951
+
2952
+ 2. PERSONALIZE \u2014 Use AI to write connection request messages
2953
+ \u2192 ai({ action: "personalize", data: [...], prompt: "Write a LinkedIn connection request referencing their recent post" })
2954
+
2955
+ 3. LIST CAMPAIGNS \u2014 Find or identify the target outreach campaign
2956
+ \u2192 campaign({ action: "list", provider: "heyreach" })
2957
+
2958
+ 4. PUSH \u2014 Add leads to LinkedIn outreach campaign
2959
+ \u2192 campaign({ action: "add_leads", campaign_id: "...", provider: "heyreach", leads: [{ linkedin_url: "..." }] })
2960
+
2961
+ ## Key principle
2962
+ LinkedIn outreach requires LinkedIn profile URLs \u2014 not emails. Extract profile data first for personalization.`,
2963
+ crm_sync: `# CRM Sync \u2014 Workflow
2964
+
2965
+ ## Steps
2966
+
2967
+ 1. CHECK \u2014 See if the person already exists in CRM
2968
+ \u2192 crm({ action: "find", query: { email: "..." } })
2969
+
2970
+ 2. CREATE or UPDATE
2971
+ \u2192 crm({ action: "create", data: { first_name: "...", last_name: "...", email: "..." } })
2972
+ \u2192 crm({ action: "update", id: "...", data: { job_title: "..." } })
2973
+
2974
+ 3. DEAL \u2014 Create a deal if this is a qualified prospect
2975
+ \u2192 crm({ action: "create_deal", data: { name: "...", person_id: "...", stage: "New" } })
2976
+
2977
+ ## Key principle
2978
+ Always search before creating to avoid duplicates. Most CRMs have built-in email dedup but better to check first.`,
2979
+ export_to_webhook: `# Export Data to Webhook \u2014 Workflow
2980
+
2981
+ Push GTM data to Clay, Make, Zapier, or any webhook endpoint for visual review or further processing.
2982
+
2983
+ ## Steps
2984
+ 1. FIND \u2014 Get your companies or contacts
2985
+ \u2192 find_companies({ icp_text: "...", limit: 50 })
2986
+ \u2192 find_people({ company_domain: "...", job_title: "CEO" })
2987
+
2988
+ 2. EXPORT \u2014 Push to webhook via fetch
2989
+ \u2192 fetch({ url: "https://your-webhook-url", method: "POST", body: { results: [...] } })
2990
+
2991
+ ## Clay Integration
2992
+ Clay table webhooks accept JSON directly:
2993
+ \u2192 fetch({ url: "https://api.clay.com/v3/sources/webhook/...", method: "POST", body: { first_name: "...", last_name: "...", company: "...", ... } })
2994
+
2995
+ Send one record per request, or batch them depending on the webhook's format.
2996
+
2997
+ ## Key principle
2998
+ Review data visually before spending enrichment credits. Export \u2192 review \u2192 enrich only the good leads.`,
2999
+ engagement_cold_email: `# Engagement Cold Email \u2014 Workflow
3000
+
3001
+ Monitor LinkedIn post engagement and auto-send personalized cold emails to engagers.
3002
+ Works with YOUR posts and ANY external post (competitors, influencers).
3003
+
3004
+ ## Steps
3005
+
3006
+ 1. CREATE CAMPAIGN \u2014 Create a PlusVibe campaign with engagement-based templates
3007
+ \u2192 campaign({ action: "create", name: "Engagement Cold Email", provider: "plusvibe" })
3008
+
3009
+ 2. ENABLE MONITORING \u2014 Turn on engagement scraping + set PlusVibe campaign for auto-push
3010
+ Works with any LinkedIn post URL \u2014 your own or external:
3011
+ \u2192 campaign({ action: "monitor", post_url: "https://linkedin.com/feed/update/...", enabled: true, plusvibe_campaign_id: "camp_xxx" })
3012
+
3013
+ For external posts, add context for personalization:
3014
+ \u2192 campaign({ action: "monitor", post_url: "...", enabled: true, plusvibe_campaign_id: "camp_xxx", post_topic: "AI agents", creator_name: "Alex Hormozi" })
3015
+
3016
+ 3. CHECK STATUS \u2014 Verify scraping is active (shows both own and external posts)
3017
+ \u2192 campaign({ action: "engagement_status" })
3018
+
3019
+ 4. (AUTOMATIC) The scrape cron runs every 10 minutes:
3020
+ - Scrapes commenters + reactors via Harvest API
3021
+ - Triggers enrichment for each engager:
3022
+ \u2022 Harvest profile lookup (company, headline)
3023
+ \u2022 Email waterfall (LeadMagic \u2192 Prospeo \u2192 Blitz \u2192 ZeroBounce)
3024
+ \u2022 Phone number lookup (Blitz API)
3025
+ - Pushes enriched leads to PlusVibe campaign with engagement context variables
3026
+
3027
+ 5. VIEW ENGAGERS \u2014 Check who has been captured and their push status
3028
+ \u2192 campaign({ action: "engagers", post_url: "...", filter: "pushed" })
3029
+
3030
+ 6. MONITOR PERFORMANCE \u2014 Check email campaign stats
3031
+ \u2192 campaign({ action: "stats", campaign_id: "camp_xxx", provider: "plusvibe" })
3032
+
3033
+ ## Manual push (alternative to auto-push)
3034
+ If you didn't set a PlusVibe campaign on the post, manually push unpushed engagers:
3035
+ \u2192 campaign({ action: "push", post_url: "...", campaign_id: "camp_xxx", limit: 20 })
3036
+
3037
+ ## One-shot workflow (no auto-monitoring)
3038
+ Use existing tools for a single extraction + push:
3039
+ 1. extract({ type: "linkedin_engagement", post_url: "...", engagement_type: "both" })
3040
+ 2. enrich({ contacts: [...], find: ["email", "phone"], verify: true })
3041
+ 3. campaign({ action: "add_leads", campaign_id: "...", leads: [...] })
3042
+
3043
+ ## Email template variables
3044
+ When using PlusVibe with engagement context, these variables are available:
3045
+ {{first_name}}, {{last_name}}, {{company_name}}, {{linkedin_url}}, {{phone}},
3046
+ {{post_topic}}, {{engagement_type}}, {{comment_text}}, {{total_engagement}}, {{opt_in_url}}
3047
+
3048
+ ## Key principle
3049
+ Always create the PlusVibe campaign and configure templates BEFORE enabling monitoring.
3050
+ The auto-push starts immediately once scraping is enabled.`,
3051
+ create_magnet: `# Create a Lead Magnet Funnel \u2014 Workflow
3052
+
3053
+ ## Quick path (all-in-one)
3054
+ magnet({ action: "launch", title: "...", archetype: "single-breakdown", content: {...} })
3055
+ \u2192 Creates magnet + funnel + email sequence + publishes in one call
3056
+
3057
+ ## Step-by-step (more control)
3058
+ 1. magnet({ action: "create", title: "...", archetype: "single-breakdown" })
3059
+ 2. magnet({ action: "update", id: "...", content: { sections: [...] } })
3060
+ 3. funnel({ action: "create", lead_magnet_id: "..." })
3061
+ 4. funnel({ action: "publish", id: "..." })
3062
+ 5. magnet({ action: "save_sequence", id: "...", emails: [
3063
+ { day: 0, subject: "Welcome!", body: "..." },
3064
+ { day: 2, subject: "Next step", body: "..." }
3065
+ ]})
3066
+ 6. magnet({ action: "activate_sequence", id: "..." })
3067
+
3068
+ ## Check results
3069
+ leads({ action: "list", lead_magnet_id: "..." })
3070
+ analytics({ action: "insights" })
3071
+
3072
+ ## Archetypes
3073
+ single-breakdown, single-system, focused-toolkit, single-calculator,
3074
+ focused-directory, mini-training, one-story, prompt, assessment, workflow
3075
+ \u2192 Call tool_help({ tool: "magnet" }) for details on each archetype`,
3076
+ content_pipeline: `# Content Creation Pipeline \u2014 Workflow
3077
+
3078
+ ## 1. Find content ingredients
3079
+ knowledge({ action: "search", query: "..." }) \u2014 find relevant knowledge
3080
+ post({ action: "formats" }) \u2014 browse proven post structures
3081
+ post({ action: "trends" }) \u2014 see what's hot
3082
+ post({ action: "recipes" }) \u2014 get AI-suggested combos
3083
+
3084
+ ## 2. Generate posts
3085
+ post({ action: "generate", knowledge_topic: "...", exploit_id: "...", instructions: "..." })
3086
+ \u2192 Requires at least one of: exploit_id, knowledge_topic, knowledge_query, trend_topic, instructions
3087
+
3088
+ ## 3. Review + edit
3089
+ post({ action: "list", status: "draft" })
3090
+ post({ action: "update", id: "...", body: "edited text..." })
3091
+
3092
+ ## 4. Publish
3093
+ post({ action: "list_accounts" }) \u2014 get LinkedIn account ID
3094
+ post({ action: "publish_linkedin", id: "...", account_id: "..." }) \u2014 post now
3095
+ post({ action: "publish", id: "..." }) \u2014 or add to scheduled queue
3096
+
3097
+ ## Batch scheduling
3098
+ magnet({ action: "schedule_week", posts: [{ body: "..." }, { body: "..." }] })`,
3099
+ dm_coaching: `# DM Coaching with Kondo \u2014 Workflow
3100
+
3101
+ AI-coached LinkedIn DM replies. Uses Kondo MCP for conversation access + our coaching methodology for style-matched, goal-adaptive replies.
3102
+
3103
+ ## Kondo Workflow
3104
+
3105
+ 1. MAP LABELS \u2014 kondo: list_inboxes() \u2014 get label name \u2192 UUID mapping. Identify which labels represent pipeline stages (opening, qualifying, meeting, follow-up, disqualified). People organize labels differently.
3106
+ 2. READ INBOX \u2014 kondo: list_inbox({ view: "NEEDS_MY_REPLY" })
3107
+ 3. FILTER \u2014 Only coach chats whose labelKeys contain a pipeline/sales label. Skip unlabeled noise (~60% is vendor pitches).
3108
+ 4. LOAD FULL HISTORY \u2014 kondo: load_chat({ profileUrn, threadKey }) THEN read_chat(). CRITICAL: read_chat alone only returns cached messages (1-2 msgs). You must load_chat first for the full thread.
3109
+ 5. GET CONTEXT (optional) \u2014 kondo: list_connections({ query: "name" }) for headline. Unreliable (~40% hit rate) \u2014 coach works without it.
3110
+ 6. COACH \u2014 Diagnose what went well/wrong earlier in the thread, then apply methodology below to generate a style-matched reply.
3111
+ 7. PUSH DRAFT \u2014 kondo: set_chat_draft({ profileUrn, threadKey, text: "coached reply" })
3112
+ 8. UPDATE LABEL \u2014 kondo: set_chat_label({ chats: [...], labelKeys: ["uuid"], action: "replace" }) if stage advanced.
3113
+ 9. SNOOZE (optional) \u2014 kondo: set_chat_reminder({ chats: [...], dueAt: epoch_ms }) for nurture conversations (4-6 weeks out).
3114
+
3115
+ ## Cardinal Rule: Style Matching
3116
+
3117
+ Before writing ANY response, analyze their exact style (capitalization, punctuation, length, formality, grammar). Your response should look like THEY could have written it. This overrides all other guidance.
3118
+
3119
+ ## Framework: Acknowledge \u2192 Value \u2192 Question
3120
+
3121
+ 1. Acknowledge & Listen \u2014 show you read their message
3122
+ 2. Add Value \u2014 share a relevant insight
3123
+ 3. Ask One Clear Question \u2014 guide conversation forward
3124
+
3125
+ Key rules: never pitch directly, one question at a time, make it personal not automated, follow up with purpose not pressure.
3126
+
3127
+ ## Qualification Ladder (ask in sequence, don't skip)
3128
+
3129
+ - **Situation**: "What's your current approach to [challenge]?" (role, tools, team)
3130
+ - **Pain**: "What's the biggest friction point?" (bottlenecks, manual work)
3131
+ - **Impact**: "How's that affecting [bigger goal]?" (revenue, growth)
3132
+ - **Vision**: "What would 'solved' look like?" (ideal state, timeline)
3133
+ - **Capability**: "Is this something you're actively working on?" (resources, priority)
3134
+ - **Commitment**: "Would it be worth 20 minutes to explore?" (timeline, next steps)
3135
+
3136
+ ## Goal-Specific Coaching
3137
+
3138
+ - **Book Meeting** (default): Focus Pain \u2192 Impact \u2192 Capability. Never suggest call before confirming real problem. Frame as "15 min to map out how to fix [pain]."
3139
+ - **Build Relationship**: No sales framing. Share value freely. Stay in Situation/Pain/Vision. Win = strong connection.
3140
+ - **Promote Content**: One share max. Only after establishing what they care about. "Thought you might find this useful."
3141
+ - **Explore Partnership**: Mutual benefit framing. Be willing to say "not a fit." Ask: "explore this further together?"
3142
+ - **Nurture Lead**: Half speed. Patience is the strategy. Advance only when THEY signal readiness. Timeline: weeks to months.
3143
+ - **Close Deal**: Remove final objections. Direct asks. Proof points matching their situation. Specific commitment + deadline.
3144
+
3145
+ ## Objection Handling
3146
+
3147
+ Acknowledge without "but" \u2192 ask for context \u2192 provide proof \u2192 suggest easy next step.
3148
+ - "Not the right time" \u2192 "What would need to change for timing to work?"
3149
+ - "Need to think about it" \u2192 "What's the main thing you're weighing?"
3150
+ - "Too expensive" \u2192 "What were you expecting it to cost?"
3151
+ - "Send me info" \u2192 "What specifically would be most useful?"
3152
+
3153
+ ## Negative Signals (flag for removal, don't coach)
3154
+
3155
+ "not interested", "please remove", "stop messaging", "too small", "just starting out", "not the right fit"
3156
+
3157
+ ## Kondo Label \u2192 Qualification Stage
3158
+
3159
+ Map the user's Kondo labels to stages by intent (not exact name): opening/new \u2192 situation, qualifying/discovery \u2192 pain, meeting/demo \u2192 capability, booked/confirmed \u2192 commitment, follow-up/nurture \u2192 commitment, disqualified/dead \u2192 skip
3160
+
3161
+ ## Coaching Output
3162
+
3163
+ When coaching a reply, provide: (1) Thread diagnosis \u2014 what went well/wrong earlier (e.g. jumped stages, pitched before establishing Impact). This is where users LEARN. (2) Style analysis, (3) Stage current \u2192 target, (4) Signals detected, (5) Coached reply (style-matched, AVQ framework), (6) Reasoning (why this approach, what to watch for).
3164
+
3165
+ Full detailed methodology with examples: see skills/dm-coaching.md`,
3166
+ qualify_inbox: `# Qualify LinkedIn Inbox with Kondo + Maestro
3167
+
3168
+ Score conversations, invites, and connections against your Maestro personas. Tag qualified contacts fast.
3169
+
3170
+ ## Inbox Qualification (start here)
3171
+
3172
+ 1. LOAD PERSONA \u2014 intel({ action: "get_persona" }) \u2192 get ICP criteria (title patterns, industries, pain points, buying signals)
3173
+ 2. MAP LABELS \u2014 kondo: list_inboxes() \u2192 discover the user's labels and identify which represent pipeline stages
3174
+ 3. READ INBOX \u2014 kondo: list_inbox({ view: "NEEDS_MY_REPLY", limit: 20 })
3175
+ 4. LOAD + READ \u2014 For each: kondo: load_chat() then read_chat() (load_chat first or you get 1-2 cached messages)
3176
+ 5. QUALIFY \u2014 For each conversation evaluate:
3177
+ - Profile fit: parse headline for title/company/industry \u2192 match against persona
3178
+ - Conversation signals: scan messages for buying signals, pain points, urgency
3179
+ - Engagement quality: are they asking questions? sharing context? or one-word replies?
3180
+ 6. SCORE \u2014 intel({ action: "score", headline: "...", company_name: "...", industry: "..." })
3181
+ 7. TAG \u2014 kondo: set_chat_label \u2192 apply the user's own pipeline labels (discovered in step 2). If none exist, ask or create them.
3182
+ 8. PRESENT \u2014 Ranked list: Name | Headline | Score | Signals | Action
3183
+
3184
+ Conversation signals beat profile signals. A slightly off-title contact describing their pain > perfect title with one-word replies.
3185
+
3186
+ ## Invite Triage
3187
+
3188
+ 1. intel({ action: "get_persona" }) \u2192 ICP criteria
3189
+ 2. kondo: list_invites({ limit: 20 }) \u2192 pending requests (name, headline, mutual count)
3190
+ 3. Parse headline \u2192 match against persona title patterns + industries
3191
+ 4. kondo: set_invite_response \u2192 accept qualified, ignore spam
3192
+ Auto-accept: title + industry match AND mutuals > 5. Auto-ignore: crypto, "guaranteed leads", emoji-heavy.
3193
+
3194
+ ## Connection Mining
3195
+
3196
+ 1. intel({ action: "get_persona" }) \u2192 get title patterns
3197
+ 2. kondo: list_connections({ query: "founder" }) \u2192 search by persona keywords (single words work best, multi-word returns 0)
3198
+ 3. Parse headline \u2192 score against persona
3199
+ 4. Check threadKeys \u2014 has chat = re-engage candidate, no chat = cold DM candidate
3200
+ 5. kondo: set_connection_label \u2192 tag qualified connections
3201
+
3202
+ ## After Qualifying
3203
+
3204
+ Run guide({ task: "dm_coaching" }) for the coaching methodology. Start with highest-scored conversations. The qualification signals become coaching context.
3205
+
3206
+ Full workflow details with gotchas: see skills/qualify-inbox.md`,
3207
+ list_tasks: `# Available GTM Workflows
3208
+
3209
+ Call guide with one of these tasks:
3210
+
3211
+ ## Prospecting & Outreach
3212
+ - build_tam \u2014 Build a TAM list (DTC/e-commerce, B2B, LinkedIn-native, or engagement-based paths)
3213
+ - enrich_list \u2014 Take a contact list and enrich with email/phone via waterfall
3214
+ - cold_outreach \u2014 Enrich + personalize + push to cold email campaign
3215
+ - linkedin_outreach \u2014 Extract profiles + personalize + push to LinkedIn campaign
3216
+ - engagement_cold_email \u2014 Monitor LinkedIn post engagement + auto-send cold emails
3217
+
3218
+ ## Content & Product
3219
+ - create_magnet \u2014 Build a lead magnet funnel (magnet \u2192 funnel \u2192 email sequence \u2192 publish)
3220
+ - content_pipeline \u2014 Create LinkedIn posts (knowledge \u2192 generate \u2192 publish)
3221
+
3222
+ ## DM Management
3223
+ - qualify_inbox \u2014 Qualify LinkedIn conversations, invites, and connections against Maestro personas
3224
+ - dm_coaching \u2014 Coach LinkedIn DM replies with Kondo (style matching, qualification ladder, goal-adaptive coaching)
3225
+
3226
+ ## Operations
3227
+ - crm_sync \u2014 Find/create/update people and deals in CRM
3228
+ - export_to_webhook \u2014 Push data to Clay, Make, Zapier, or any webhook for review
3229
+
3230
+ For any task: always dry_run enrichment batches > 5 to preview cost before executing.`
3231
+ };
3232
+
3233
+ export {
3234
+ prospectTools,
3235
+ enrichTools,
3236
+ extractTools,
3237
+ fetchTools,
3238
+ aiTools,
3239
+ campaignTools,
3240
+ crmTools,
3241
+ statusTools,
3242
+ configureTools,
3243
+ reviewTools,
3244
+ batchTools,
3245
+ recipeTools,
3246
+ provisionTools,
3247
+ listTools,
3248
+ maestroTools,
3249
+ engagementTools,
3250
+ dfyTools,
3251
+ tamTools,
3252
+ knowledgeTools,
3253
+ mixerTools,
3254
+ dmCoachTools,
3255
+ launchTools,
3256
+ exploitTools,
3257
+ modeTools,
3258
+ magnetTools,
3259
+ funnelTools,
3260
+ postTools,
3261
+ emailSequenceTools,
3262
+ leadsTools,
3263
+ analyticsTools,
3264
+ TOOL_DESCRIPTIONS,
3265
+ buildCatalogText,
3266
+ tools,
3267
+ mcpTools,
3268
+ toolsByName,
3269
+ toolCategories,
3270
+ workflowRecipes
3271
+ };
3272
+ //# sourceMappingURL=chunk-M25KLO7T.js.map