@sellable/mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/.claude-plugin/plugin.json +12 -0
  2. package/.mcp.json +9 -0
  3. package/README.md +355 -0
  4. package/dist/api.d.ts +21 -0
  5. package/dist/api.js +73 -0
  6. package/dist/auth.d.ts +60 -0
  7. package/dist/auth.js +246 -0
  8. package/dist/engage-memory.d.ts +63 -0
  9. package/dist/engage-memory.js +354 -0
  10. package/dist/index-dev.d.ts +2 -0
  11. package/dist/index-dev.js +17 -0
  12. package/dist/index.d.ts +7 -0
  13. package/dist/index.js +8 -0
  14. package/dist/server.d.ts +1 -0
  15. package/dist/server.js +499 -0
  16. package/dist/skills.d.ts +11 -0
  17. package/dist/skills.js +97 -0
  18. package/dist/tools/auth.d.ts +30 -0
  19. package/dist/tools/auth.js +124 -0
  20. package/dist/tools/blueprint-commit.d.ts +174 -0
  21. package/dist/tools/blueprint-commit.js +286 -0
  22. package/dist/tools/bootstrap.d.ts +64 -0
  23. package/dist/tools/bootstrap.js +246 -0
  24. package/dist/tools/campaigns.d.ts +589 -0
  25. package/dist/tools/campaigns.js +892 -0
  26. package/dist/tools/cells.d.ts +58 -0
  27. package/dist/tools/cells.js +48 -0
  28. package/dist/tools/context.d.ts +88 -0
  29. package/dist/tools/context.js +271 -0
  30. package/dist/tools/csv-domains.d.ts +73 -0
  31. package/dist/tools/csv-domains.js +464 -0
  32. package/dist/tools/csv-linkedin.d.ts +102 -0
  33. package/dist/tools/csv-linkedin.js +712 -0
  34. package/dist/tools/direct-campaigns.d.ts +240 -0
  35. package/dist/tools/direct-campaigns.js +250 -0
  36. package/dist/tools/engage-bootstrap.d.ts +94 -0
  37. package/dist/tools/engage-bootstrap.js +205 -0
  38. package/dist/tools/engage-discovery.d.ts +78 -0
  39. package/dist/tools/engage-discovery.js +150 -0
  40. package/dist/tools/engage-memory.d.ts +181 -0
  41. package/dist/tools/engage-memory.js +143 -0
  42. package/dist/tools/engage-state.d.ts +72 -0
  43. package/dist/tools/engage-state.js +62 -0
  44. package/dist/tools/enrichment.d.ts +167 -0
  45. package/dist/tools/enrichment.js +174 -0
  46. package/dist/tools/flow-preflight.d.ts +68 -0
  47. package/dist/tools/flow-preflight.js +138 -0
  48. package/dist/tools/framework.d.ts +44 -0
  49. package/dist/tools/framework.js +153 -0
  50. package/dist/tools/interaction-mode.d.ts +27 -0
  51. package/dist/tools/interaction-mode.js +102 -0
  52. package/dist/tools/leads.d.ts +2417 -0
  53. package/dist/tools/leads.js +2307 -0
  54. package/dist/tools/linkedin.d.ts +210 -0
  55. package/dist/tools/linkedin.js +229 -0
  56. package/dist/tools/navigation.d.ts +91 -0
  57. package/dist/tools/navigation.js +381 -0
  58. package/dist/tools/one-off.d.ts +229 -0
  59. package/dist/tools/one-off.js +273 -0
  60. package/dist/tools/processing.d.ts +70 -0
  61. package/dist/tools/processing.js +56 -0
  62. package/dist/tools/prompts.d.ts +211 -0
  63. package/dist/tools/prompts.js +210 -0
  64. package/dist/tools/provider-preflight.d.ts +21 -0
  65. package/dist/tools/provider-preflight.js +59 -0
  66. package/dist/tools/readiness.d.ts +261 -0
  67. package/dist/tools/readiness.js +510 -0
  68. package/dist/tools/rows.d.ts +126 -0
  69. package/dist/tools/rows.js +105 -0
  70. package/dist/tools/rubrics.d.ts +497 -0
  71. package/dist/tools/rubrics.js +681 -0
  72. package/dist/tools/senders.d.ts +44 -0
  73. package/dist/tools/senders.js +69 -0
  74. package/dist/tools/sequencer.d.ts +127 -0
  75. package/dist/tools/sequencer.js +194 -0
  76. package/dist/tools/tables.d.ts +35 -0
  77. package/dist/tools/tables.js +36 -0
  78. package/dist/tools/verify-row.d.ts +36 -0
  79. package/dist/tools/verify-row.js +38 -0
  80. package/dist/tools/workspaces.d.ts +140 -0
  81. package/dist/tools/workspaces.js +139 -0
  82. package/dist/utils/workspace-root.d.ts +1 -0
  83. package/dist/utils/workspace-root.js +39 -0
  84. package/package.json +46 -0
  85. package/skills/building-gtm-tables/SKILL.md +216 -0
  86. package/skills/building-gtm-tables/core/auto-execute.yaml +19 -0
  87. package/skills/building-gtm-tables/core/blueprint-schema.json +72 -0
  88. package/skills/building-gtm-tables/references/brief-to-blueprint.md +334 -0
  89. package/skills/building-gtm-tables/references/column-type-catalog.md +318 -0
  90. package/skills/building-gtm-tables/references/common-blueprints.fixtures.ts +199 -0
  91. package/skills/building-gtm-tables/references/common-blueprints.md +44 -0
  92. package/skills/building-gtm-tables/references/failure-taxonomy.md +197 -0
  93. package/skills/building-gtm-tables/references/uat-seed-prompts.md +37 -0
  94. package/skills/building-gtm-tables/references/verify-loop.md +74 -0
  95. package/skills/campaign-messages/SKILL.md +173 -0
  96. package/skills/campaign-messages/flow.v1.json +75 -0
  97. package/skills/craft-message/SKILL.md +401 -0
  98. package/skills/create-campaign/ARCHITECTURE.md +232 -0
  99. package/skills/create-campaign/DISCUSS.md +296 -0
  100. package/skills/create-campaign/FLOW_ASCII.md +240 -0
  101. package/skills/create-campaign/HOST-PARITY-CHECKLIST.md +49 -0
  102. package/skills/create-campaign/README.md +142 -0
  103. package/skills/create-campaign/SKILL.md +286 -0
  104. package/skills/create-campaign/context/README.md +67 -0
  105. package/skills/create-campaign/context/_TEMPLATE.md +12 -0
  106. package/skills/create-campaign/context/context.md +35 -0
  107. package/skills/create-campaign/context/learnings.md +16 -0
  108. package/skills/create-campaign/context/registry.json +19 -0
  109. package/skills/create-campaign/core/flow.v1.json +217 -0
  110. package/skills/create-campaign/core/policy.md +191 -0
  111. package/skills/create-campaign/core/providers/apollo.json +35 -0
  112. package/skills/create-campaign/core/providers/prospeo.json +34 -0
  113. package/skills/create-campaign/core/providers/registry.json +31 -0
  114. package/skills/create-campaign/core/providers/sales-nav.json +37 -0
  115. package/skills/create-campaign/core/providers/signal-discovery.json +42 -0
  116. package/skills/create-campaign/references/brief-template.md +64 -0
  117. package/skills/create-campaign/references/campaign-quality.md +84 -0
  118. package/skills/create-campaign/references/copy-calibration-examples.md +120 -0
  119. package/skills/create-campaign/references/offer-patterns.md +108 -0
  120. package/skills/create-campaign/references/provider-selection-strategy.md +212 -0
  121. package/skills/create-campaign/references/question-examples.md +167 -0
  122. package/skills/create-campaign/references/token-fill-examples.md +81 -0
  123. package/skills/create-campaign-brief/ARCHITECTURE.md +72 -0
  124. package/skills/create-campaign-brief/DISCUSS.md +64 -0
  125. package/skills/create-campaign-brief/README.md +176 -0
  126. package/skills/create-campaign-brief/SKILL.md +537 -0
  127. package/skills/create-campaign-brief/references/brief-synthesis-rules.md +100 -0
  128. package/skills/create-campaign-brief/references/brief-template.md +220 -0
  129. package/skills/create-campaign-brief/references/campaign-idea-options.md +30 -0
  130. package/skills/create-campaign-brief/references/copy-appendix-template.md +62 -0
  131. package/skills/create-campaign-brief/references/draft-lifecycle.md +23 -0
  132. package/skills/create-campaign-brief/references/examples/MANIFEST.json +89 -0
  133. package/skills/create-campaign-brief/references/examples/briefs/clover.md +223 -0
  134. package/skills/create-campaign-brief/references/examples/briefs/galley.md +222 -0
  135. package/skills/create-campaign-brief/references/examples/briefs/gelee.md +220 -0
  136. package/skills/create-campaign-brief/references/examples/briefs/hey-digital.md +234 -0
  137. package/skills/create-campaign-brief/references/examples/briefs/persona.md +231 -0
  138. package/skills/create-campaign-brief/references/examples/briefs/revvix.md +220 -0
  139. package/skills/create-campaign-brief/references/examples/briefs/sellable-dev.md +220 -0
  140. package/skills/create-campaign-brief/references/examples/briefs/superposition.md +233 -0
  141. package/skills/create-campaign-brief/references/examples/briefs/superpower.md +219 -0
  142. package/skills/create-campaign-brief/references/examples/briefs/westpark-villas.md +220 -0
  143. package/skills/create-campaign-brief/references/icp-lock-question-bank.md +43 -0
  144. package/skills/create-campaign-brief/references/messaging-inputs.md +58 -0
  145. package/skills/create-campaign-brief/references/output-acceptance-rubric.md +62 -0
  146. package/skills/create-campaign-brief/references/phase75-active-runtime-message-pack.md +248 -0
  147. package/skills/create-campaign-brief/references/phase75-canonical-brief-template.md +319 -0
  148. package/skills/create-campaign-brief/references/phase75-good-brief-and-messaging-examples.md +445 -0
  149. package/skills/create-campaign-brief/references/quick-research-protocol.md +39 -0
  150. package/skills/create-campaign-brief/references/reference-sheet-protocol.md +60 -0
  151. package/skills/create-campaign-brief/references/zero-shot-iteration-rules.md +66 -0
  152. package/skills/create-campaign-v2/SKILL.md +1619 -0
  153. package/skills/create-campaign-v2/core/auto-execute.README.md +219 -0
  154. package/skills/create-campaign-v2/core/auto-execute.yaml +121 -0
  155. package/skills/create-campaign-v2/core/flow.v2.json +1643 -0
  156. package/skills/create-campaign-v2/core/policy.md +82 -0
  157. package/skills/create-campaign-v2/references/ai-tells.md +253 -0
  158. package/skills/create-campaign-v2/references/approval-gate-framing.md +346 -0
  159. package/skills/create-campaign-v2/references/draft-lifecycle.md +110 -0
  160. package/skills/create-campaign-v2/references/escalation-ladder.md +119 -0
  161. package/skills/create-campaign-v2/references/filter-leads.md +495 -0
  162. package/skills/create-campaign-v2/references/final-handoff-contract.md +176 -0
  163. package/skills/create-campaign-v2/references/gold-standard-message-examples.md +394 -0
  164. package/skills/create-campaign-v2/references/gold-standard-message-patterns.md +314 -0
  165. package/skills/create-campaign-v2/references/gold-standard-message-validation-example.md +212 -0
  166. package/skills/create-campaign-v2/references/lead-validation-preview.md +172 -0
  167. package/skills/create-campaign-v2/references/parallel-critique-protocol.md +368 -0
  168. package/skills/create-campaign-v2/references/sample-validation-loop.md +289 -0
  169. package/skills/create-campaign-v2/references/step-13-import-leads.md +151 -0
  170. package/skills/create-campaign-v2/references/step-15-re-cascade.md +90 -0
  171. package/skills/create-campaign-v2/references/thomas-revision-filters.md +521 -0
  172. package/skills/create-campaign-v2/references/thomas-variant-selection.md +202 -0
  173. package/skills/create-campaign-v2/references/tier-routing-matrix.md +66 -0
  174. package/skills/create-campaign-v2/references/validation-criteria.md +367 -0
  175. package/skills/create-campaign-v2/references/watch-link-handoff.md +106 -0
  176. package/skills/create-campaign-v2-validation/SKILL.md +296 -0
  177. package/skills/create-post/SKILL.md +1308 -0
  178. package/skills/create-rubric/SKILL.md +251 -0
  179. package/skills/engage/SKILL.md +549 -0
  180. package/skills/engage/core/README.md +23 -0
  181. package/skills/engage/core/proven-searches.json +11 -0
  182. package/skills/engage/core/style-guide.template.md +47 -0
  183. package/skills/engage/core/tracked-people.json +10 -0
  184. package/skills/enrich-prospects/SKILL.md +97 -0
  185. package/skills/find-leads/SKILL.md +467 -0
  186. package/skills/generate-messages/SKILL.md +2361 -0
  187. package/skills/interview/SKILL.md +132 -0
  188. package/skills/interview/core/ENGAGE_STYLE_GUIDE.template.md +54 -0
  189. package/skills/interview/core/ICP.template.md +54 -0
  190. package/skills/interview/core/VOICE_PROFILE.template.md +101 -0
  191. package/skills/providers/apollo.md +520 -0
  192. package/skills/providers/prospeo.md +398 -0
  193. package/skills/providers/sales-nav.md +372 -0
  194. package/skills/providers/signal-discovery.md +495 -0
  195. package/skills/research/SKILL.md +258 -0
  196. package/skills/research/config.json +9 -0
  197. package/skills/research/override.md +13 -0
  198. package/skills/research-prospect/SKILL.md +99 -0
  199. package/skills/research-sender/SKILL.md +158 -0
  200. package/skills/workflow-sequences/SKILL.md +85 -0
@@ -0,0 +1,334 @@
1
+ # Brief To Blueprint
2
+
3
+ Use this recipe to show the reasoning trace before the final JSON. The user
4
+ does not need every internal detail, but the agent should be able to explain why
5
+ each column exists and how it is wired.
6
+
7
+ ## TOC
8
+
9
+ - [Decomposition recipe](#decomposition-recipe)
10
+ - [Example 1: Rank my prospect list against my ICP](#example-1-rank-my-prospect-list-against-my-icp)
11
+ - [Example 2: Enrich + score + send invite to top-scoring prospects](#example-2-enrich--score--send-invite-to-top-scoring-prospects)
12
+ - [Example 3: Enrich + score + generate approved campaign messages](#example-3-enrich--score--generate-approved-campaign-messages)
13
+ - [Example 4: Pull each prospect's last LinkedIn post and summarize it](#example-4-pull-each-prospects-last-linkedin-post-and-summarize-it)
14
+
15
+ ## Decomposition recipe
16
+
17
+ 1. Identify row inputs. Ask what each row already has: LinkedIn URL, email,
18
+ company domain, raw JSON, campaign offer id, message text, or post URL.
19
+ 2. Pick enrichment recipe. Most prospect-fit workflows use a `http_request`
20
+ column named "Enrich Prospect" with endpoint `/api/v4/enrich-prospect`.
21
+ 3. Pick scoring criteria. If the goal includes ranking, filtering, or deciding
22
+ who deserves action, add `score_icp_mcp` with a natural-language rubric.
23
+ 4. Pick action/generation columns. Use LinkedIn action types for outreach,
24
+ Generate Message for campaign-attached production messages, and AI Column for
25
+ custom research/summarization/classification.
26
+ 5. Wire dependencies explicitly. Every downstream column's `inputMapping`
27
+ references the producer by id, and every edge mirrors the dependency.
28
+ 6. Treat Enrich Prospect as the baseline producer for Sellable-specific
29
+ prospect context. `score_icp_mcp.inputMapping.enrichedProspectId` and
30
+ `generate_message.inputMapping.enrichedProspectId` should point to the
31
+ `http_request` column named "Enrich Prospect" unless the user says an
32
+ enriched prospect id already exists.
33
+
34
+ ## Example 1: Rank my prospect list against my ICP
35
+
36
+ User ask: "Rank my prospect list against my ICP. I have LinkedIn URLs and want a
37
+ score for each row."
38
+
39
+ Reasoning trace:
40
+
41
+ - Step 1: row has `linkedin_url`, so the seed input is a `linkedin_url` column.
42
+ - Step 2: ICP judgment needs title, company, seniority, and profile context, so
43
+ add Enrich Prospect as `http_request` with `/api/v4/enrich-prospect`.
44
+ - Step 3: ranking is required, so add `score_icp_mcp` with user-readable criteria.
45
+ - Step 4: no action or message generation is requested, so stop after scoring.
46
+ - Step 5: wire `score_icp_mcp.inputMapping.enrichedProspectId` to the
47
+ `enrich_prospect` column id; mirror that as an edge.
48
+
49
+ Final JSON:
50
+
51
+ ```json
52
+ {
53
+ "columns": [
54
+ {
55
+ "id": "linkedin_url",
56
+ "type": "linkedin_url",
57
+ "name": "LinkedIn URL",
58
+ "config": {}
59
+ },
60
+ {
61
+ "id": "enrich_prospect",
62
+ "type": "http_request",
63
+ "name": "Enrich Prospect",
64
+ "config": {
65
+ "method": "POST",
66
+ "endpoint": "/api/v4/enrich-prospect",
67
+ "body": "{\"linkedinUrl\":\"{{LinkedIn URL}}\"}"
68
+ },
69
+ "inputMapping": { "linkedinUrl": "linkedin_url" }
70
+ },
71
+ {
72
+ "id": "score_icp_mcp",
73
+ "type": "score_icp_mcp",
74
+ "name": "ICP Score",
75
+ "config": {
76
+ "rubric": [
77
+ "Matches the named buyer persona.",
78
+ "Company size and segment match the ICP.",
79
+ "Profile evidence shows ownership of the relevant problem."
80
+ ]
81
+ },
82
+ "inputMapping": { "enrichedProspectId": "enrich_prospect" }
83
+ }
84
+ ],
85
+ "edges": [
86
+ { "from": "linkedin_url", "to": "enrich_prospect", "via": "linkedinUrl" },
87
+ {
88
+ "from": "enrich_prospect",
89
+ "to": "score_icp_mcp",
90
+ "via": "enrichedProspectId"
91
+ }
92
+ ]
93
+ }
94
+ ```
95
+
96
+ ## Example 2: Enrich + score + send invite to top-scoring prospects
97
+
98
+ User ask: "Enrich this list, score everyone, and send a LinkedIn invite only to
99
+ top-scoring prospects."
100
+
101
+ Reasoning trace:
102
+
103
+ - Step 1: row has `linkedin_url`, so use it as the seed and action target.
104
+ - Step 2: score quality depends on profile/company facts, so add Enrich
105
+ Prospect as `http_request`.
106
+ - Step 3: the action threshold needs a numeric score, so add `score_icp_mcp` and set
107
+ the rubric from the user's ICP.
108
+ - Step 4: user asked for invites, so add `send_invite`.
109
+ - Step 5: wire enrichment to score, wire LinkedIn URL to invite, and gate invite
110
+ with `{{score_icp_mcp.result.score}} >= 70`.
111
+
112
+ Final JSON:
113
+
114
+ ```json
115
+ {
116
+ "columns": [
117
+ {
118
+ "id": "linkedin_url",
119
+ "type": "linkedin_url",
120
+ "name": "LinkedIn URL",
121
+ "config": {}
122
+ },
123
+ {
124
+ "id": "enrich_prospect",
125
+ "type": "http_request",
126
+ "name": "Enrich Prospect",
127
+ "config": {
128
+ "method": "POST",
129
+ "endpoint": "/api/v4/enrich-prospect",
130
+ "body": "{\"linkedinUrl\":\"{{LinkedIn URL}}\"}"
131
+ },
132
+ "inputMapping": { "linkedinUrl": "linkedin_url" }
133
+ },
134
+ {
135
+ "id": "score_icp_mcp",
136
+ "type": "score_icp_mcp",
137
+ "name": "ICP Score",
138
+ "config": {
139
+ "rubric": [
140
+ "Decision-maker or strong influencer for outbound/GTM tooling.",
141
+ "Company has an active sales-led or founder-led growth motion.",
142
+ "Evidence suggests urgency around pipeline quality."
143
+ ]
144
+ },
145
+ "inputMapping": { "enrichedProspectId": "enrich_prospect" }
146
+ },
147
+ {
148
+ "id": "send_invite",
149
+ "type": "send_invite",
150
+ "name": "Invite",
151
+ "config": { "actionConfig": { "actionType": "INVITE" } },
152
+ "inputMapping": { "linkedinUrl": "linkedin_url" },
153
+ "runCondition": "{{score_icp_mcp.result.score}} >= 70"
154
+ }
155
+ ],
156
+ "edges": [
157
+ { "from": "linkedin_url", "to": "enrich_prospect", "via": "linkedinUrl" },
158
+ {
159
+ "from": "enrich_prospect",
160
+ "to": "score_icp_mcp",
161
+ "via": "enrichedProspectId"
162
+ },
163
+ { "from": "linkedin_url", "to": "send_invite", "via": "linkedinUrl" },
164
+ { "from": "score_icp_mcp", "to": "send_invite", "via": "runCondition" }
165
+ ]
166
+ }
167
+ ```
168
+
169
+ ## Example 3: Enrich + score + generate approved campaign messages
170
+
171
+ User ask: "For qualified prospects, enrich the profile, score fit, and generate
172
+ the campaign message."
173
+
174
+ Reasoning trace:
175
+
176
+ - Step 1: row has `linkedin_url`; the campaign-backed table also has or can
177
+ receive a `campaign_offer_id`.
178
+ - Step 2: both ICP scoring and message generation need rich prospect context, so
179
+ add Enrich Prospect as `http_request`.
180
+ - Step 3: add `score_icp_mcp` for the qualification threshold.
181
+ - Step 4: add `generate_message` for the production message-generation flow.
182
+ - Step 5: wire both `score_icp_mcp.inputMapping.enrichedProspectId` and
183
+ `generate_message.inputMapping.enrichedProspectId` to `enrich_prospect`.
184
+
185
+ Final JSON:
186
+
187
+ ```json
188
+ {
189
+ "columns": [
190
+ {
191
+ "id": "linkedin_url",
192
+ "type": "text",
193
+ "name": "LinkedIn URL",
194
+ "config": {}
195
+ },
196
+ {
197
+ "id": "campaign_offer_id",
198
+ "type": "text",
199
+ "name": "Campaign Offer ID",
200
+ "config": {}
201
+ },
202
+ {
203
+ "id": "enrich_prospect",
204
+ "type": "http_request",
205
+ "name": "Enrich Prospect",
206
+ "config": {
207
+ "inputMapping": {
208
+ "method": { "value": "POST" },
209
+ "endpoint": { "value": "/api/v4/enrich-prospect" },
210
+ "body": { "value": "{\"linkedinUrl\":\"{{LinkedIn URL}}\"}" }
211
+ }
212
+ },
213
+ "inputMapping": { "linkedinUrl": "linkedin_url" }
214
+ },
215
+ {
216
+ "id": "score_icp_mcp",
217
+ "type": "score_icp_mcp",
218
+ "name": "ICP Score",
219
+ "config": {
220
+ "rubric": [
221
+ {
222
+ "checkName": "buyer_fit",
223
+ "criterion": "Prospect matches the target buyer profile.",
224
+ "description": "Role, seniority, and company context match the ICP.",
225
+ "reason": "Message generation should focus on qualified buyers.",
226
+ "isRequiredCheck": "true",
227
+ "allowPartialCredit": "true"
228
+ }
229
+ ]
230
+ },
231
+ "inputMapping": { "enrichedProspectId": "enrich_prospect" }
232
+ },
233
+ {
234
+ "id": "generate_message",
235
+ "type": "generate_message",
236
+ "name": "Generate Message",
237
+ "config": {},
238
+ "inputMapping": {
239
+ "campaignOfferId": "campaign_offer_id",
240
+ "enrichedProspectId": "enrich_prospect"
241
+ },
242
+ "runCondition": "{{ICP Score.score}} >= 70"
243
+ }
244
+ ],
245
+ "edges": [
246
+ { "from": "linkedin_url", "to": "enrich_prospect", "via": "linkedinUrl" },
247
+ {
248
+ "from": "enrich_prospect",
249
+ "to": "score_icp_mcp",
250
+ "via": "enrichedProspectId"
251
+ },
252
+ {
253
+ "from": "campaign_offer_id",
254
+ "to": "generate_message",
255
+ "via": "campaignOfferId"
256
+ },
257
+ {
258
+ "from": "enrich_prospect",
259
+ "to": "generate_message",
260
+ "via": "enrichedProspectId"
261
+ },
262
+ {
263
+ "from": "score_icp_mcp",
264
+ "to": "generate_message",
265
+ "via": "runCondition"
266
+ }
267
+ ]
268
+ }
269
+ ```
270
+
271
+ ## Example 4: Pull each prospect's last LinkedIn post and summarize it
272
+
273
+ User ask: "For every prospect, pull their recent LinkedIn activity and summarize
274
+ the most relevant post in one line."
275
+
276
+ Reasoning trace:
277
+
278
+ - Step 1: row has `linkedin_url`; the row may also have a text instruction for
279
+ what relevance means.
280
+ - Step 2: no ICP score is requested; enrichment may be unnecessary if the AI
281
+ prompt can search from the LinkedIn URL directly.
282
+ - Step 3: no scoring criteria are needed.
283
+ - Step 4: use `ai_column` because the task is custom research and summarization.
284
+ - Step 5: wire the LinkedIn URL and optional prompt text to the AI column so
285
+ missing seed data is visible during verification.
286
+
287
+ Final JSON:
288
+
289
+ ```json
290
+ {
291
+ "columns": [
292
+ {
293
+ "id": "linkedin_url",
294
+ "type": "linkedin_url",
295
+ "name": "LinkedIn URL",
296
+ "config": {}
297
+ },
298
+ {
299
+ "id": "research_focus",
300
+ "type": "text",
301
+ "name": "Research Focus",
302
+ "config": {}
303
+ },
304
+ {
305
+ "id": "linkedin_post_summary",
306
+ "type": "ai_column",
307
+ "name": "LinkedIn Post Summary",
308
+ "config": {
309
+ "aiConfig": {
310
+ "modelName": "google/gemini-3.1-flash-lite-preview",
311
+ "systemPrompt": "Use only observable public LinkedIn activity.",
312
+ "userPrompt": "Find recent LinkedIn activity for {{LinkedIn URL}}. Focus on {{Research Focus}}. Return one concise sentence.",
313
+ "outputFields": [{ "name": "summary", "type": "text" }],
314
+ "enableWebSearch": true,
315
+ "maxSearchQueries": 3
316
+ },
317
+ "processing": { "autoUpdate": true }
318
+ },
319
+ "inputMapping": {
320
+ "linkedinUrl": "linkedin_url",
321
+ "focus": "research_focus"
322
+ }
323
+ }
324
+ ],
325
+ "edges": [
326
+ {
327
+ "from": "linkedin_url",
328
+ "to": "linkedin_post_summary",
329
+ "via": "linkedinUrl"
330
+ },
331
+ { "from": "research_focus", "to": "linkedin_post_summary", "via": "focus" }
332
+ ]
333
+ }
334
+ ```
@@ -0,0 +1,318 @@
1
+ # Column Type Catalog
2
+
3
+ Display names in this catalog are sourced from
4
+ `getColumnTypeConfig(type).displayName`. Do not paraphrase them.
5
+
6
+ ## TOC
7
+
8
+ - [Lead Data](#lead-data)
9
+ - [Enrichment](#enrichment)
10
+ - [Scoring](#scoring)
11
+ - [LinkedIn Actions](#linkedin-actions)
12
+ - [Generation](#generation)
13
+ - [Data & Logic](#data--logic)
14
+
15
+ ## Lead Data
16
+
17
+ ### Select
18
+
19
+ - type: `select`
20
+ - displayName: `Select`
21
+ - category: Lead Data
22
+ - inputs: `options` required text, comma-separated list of allowed values.
23
+ - outputs: selected option value.
24
+ - when to use: Use for categorical row state such as channel, tier, or manual review labels.
25
+ - when NOT to use: Do not use for free-form notes or generated classifications with unknown labels.
26
+
27
+ ### Sequence Status
28
+
29
+ - type: `sequence_status`
30
+ - displayName: `Sequence Status`
31
+ - category: Lead Data
32
+ - inputs: `options` required text, usually system-owned defaults.
33
+ - outputs: current sequence state.
34
+ - when to use: Use when a sequence pipeline needs a visible state column.
35
+ - when NOT to use: Do not use as an action executor; it records state only.
36
+
37
+ ### Reply Sentiment
38
+
39
+ - type: `reply_sentiment`
40
+ - displayName: `Reply Sentiment`
41
+ - category: Lead Data
42
+ - inputs: `options` required text, usually interested/not_interested/out_of_office/question/neutral/negative.
43
+ - outputs: sentiment label.
44
+ - when to use: Use for reply triage state after messages start receiving responses.
45
+ - when NOT to use: Do not use for ICP fit scoring; use `score_icp_mcp` for prospect fit.
46
+
47
+ ### Date/Time
48
+
49
+ - type: `datetime`
50
+ - displayName: `Date/Time`
51
+ - category: Lead Data
52
+ - inputs: none.
53
+ - outputs: ISO-like date/time value.
54
+ - when to use: Use for system-owned scheduling timestamps.
55
+ - when NOT to use: Do not use to wait; use `wait` for sequence timing.
56
+
57
+ ### Next Action
58
+
59
+ - type: `next_action_at`
60
+ - displayName: `Next Action`
61
+ - category: Lead Data
62
+ - inputs: none.
63
+ - outputs: next scheduled action timestamp.
64
+ - when to use: Use when the sequence engine needs a visible next-action time.
65
+ - when NOT to use: Do not hand-author this as a scoring or enrichment input.
66
+
67
+ ### Sent At
68
+
69
+ - type: `sent_at`
70
+ - displayName: `Sent At`
71
+ - category: Lead Data
72
+ - inputs: none.
73
+ - outputs: sent timestamp.
74
+ - when to use: Use to display when a LinkedIn action or message was sent.
75
+ - when NOT to use: Do not use as a delay mechanism; use `wait`.
76
+
77
+ ### LinkedIn URL
78
+
79
+ - type: `linkedin_url`
80
+ - displayName: `LinkedIn URL`
81
+ - category: Lead Data
82
+ - inputs: none; user or import supplies the cell value.
83
+ - outputs: prospect LinkedIn profile URL string.
84
+ - when to use: Use as the canonical prospect identity input for enrichment and LinkedIn actions.
85
+ - when NOT to use: Do not put post URLs here; use the action-specific post URL mapping.
86
+
87
+ ### JSON
88
+
89
+ - type: `json`
90
+ - displayName: `JSON`
91
+ - category: Lead Data
92
+ - inputs: none; user, import, or webhook supplies structured JSON.
93
+ - outputs: JSON object or array.
94
+ - when to use: Use when a row carries structured payload data.
95
+ - when NOT to use: Do not use when a typed column with known inputs exists.
96
+
97
+ ### Example
98
+
99
+ - type: `example_checkbox`
100
+ - displayName: `Example`
101
+ - category: Lead Data
102
+ - inputs: none.
103
+ - outputs: boolean marker for style examples.
104
+ - when to use: Use to mark rows as AI style examples for message-generation flows.
105
+ - when NOT to use: Do not use as a general pass/fail gate; use `checkbox`.
106
+
107
+ ### Inbound Webhook
108
+
109
+ - type: `inbound_webhook`
110
+ - displayName: `Inbound Webhook`
111
+ - category: Lead Data
112
+ - inputs: none.
113
+ - outputs: received JSON payload and webhook metadata.
114
+ - when to use: Use when rows are populated by external webhook events.
115
+ - when NOT to use: Do not use for polling APIs; use `http_request`.
116
+
117
+ ## Enrichment
118
+
119
+ ### Enrich Prospect preset
120
+
121
+ - type: `http_request`
122
+ - displayName: `HTTP Request`
123
+ - category: Enrichment preset
124
+ - inputs: `method` POST, `endpoint` `/api/v4/enrich-prospect`, body mapped from `linkedin_url`.
125
+ Store body as a JSON string, matching the app UI: `{"linkedinUrl":"{{linkedin_url}}"}`.
126
+ - outputs: root `id` (the EnrichedProspect id), profile fields, company fields, and HTTP metadata from the enrichment endpoint.
127
+ - when to use: Use this named `http_request` column as "Enrich Prospect" before `score_icp_mcp`, Generate Message, or action routing that needs profile/company facts.
128
+ - when NOT to use: Do not invent an `enrich_person` type; deprecated enrichment types migrate to `http_request`.
129
+
130
+ ## Scoring
131
+
132
+ ### ICP Rubric Score
133
+
134
+ - type: `score_icp_mcp`
135
+ - displayName: `MCP ICP Score`
136
+ - category: Scoring
137
+ - purpose: MCP-safe AI ICP scorer for new blueprints. It is separate from
138
+ legacy `score_icp`, which belongs to older saved tables and a different config
139
+ contract.
140
+ - inputs: optional `enrichedProspectId` from Enrich Prospect; optional `linkedinUrl` fallback.
141
+ - canonical wiring: in blueprint form use
142
+ `"inputMapping": { "enrichedProspectId": "enrich_prospect" }`; the commit
143
+ tool must materialize it as `{{Enrich Prospect.id}}` using
144
+ the real column id.
145
+ - outputs: `score`, criteria-level reasoning, and fit evidence.
146
+ - when to use: Use when the table must rank or qualify prospects against natural-language ICP criteria.
147
+ - when NOT to use: Do not use legacy `score_icp` or the old
148
+ `score_icp_rubric` alias in MCP blueprints. Do not use this for
149
+ deterministic boolean checks; use `checkbox` or `formula`.
150
+
151
+ ## LinkedIn Actions
152
+
153
+ ### Check Open Profile
154
+
155
+ - type: `is_open_profile`
156
+ - displayName: `Check Open Profile`
157
+ - category: LinkedIn Actions
158
+ - inputs: required `linkedin_url`.
159
+ - outputs: boolean open-profile decision and lookup metadata.
160
+ - when to use: Use before selecting open-profile InMail behavior.
161
+ - when NOT to use: Do not use to check first-degree connection; use `check_connection`.
162
+
163
+ ### Check Connection
164
+
165
+ - type: `check_connection`
166
+ - displayName: `Check Connection`
167
+ - category: LinkedIn Actions
168
+ - inputs: required `lead_linkedin_id`.
169
+ - outputs: connection status.
170
+ - when to use: Use before choosing DM versus invite/InMail paths.
171
+ - when NOT to use: Do not use with raw profile URLs unless a producer resolves the LinkedIn id first.
172
+
173
+ ### LinkedIn Action
174
+
175
+ - type: `action`
176
+ - displayName: `LinkedIn Action`
177
+ - category: LinkedIn Actions
178
+ - inputs: optional configured `actionType`.
179
+ - outputs: action execution status and event-wait metadata.
180
+ - when to use: Use for generic or template-driven LinkedIn action execution.
181
+ - when NOT to use: Prefer the specialized action types below when the user asked for a specific action.
182
+
183
+ ### Invite
184
+
185
+ - type: `send_invite`
186
+ - displayName: `Invite`
187
+ - category: LinkedIn Actions
188
+ - inputs: required `linkedinUrl`; optional `connectionNote`.
189
+ - outputs: invite send status and connection-accept wait state.
190
+ - when to use: Use to send a LinkedIn connection request after qualification.
191
+ - when NOT to use: Do not use for already-connected prospects; use `send_dm`.
192
+
193
+ ### InMail (Open Profile)
194
+
195
+ - type: `send_inmail_open`
196
+ - displayName: `InMail (Open Profile)`
197
+ - category: LinkedIn Actions
198
+ - inputs: required `linkedinUrl`, `subject`, and `message`.
199
+ - outputs: open-profile InMail status and fallback metadata.
200
+ - when to use: Use when Check Open Profile says free InMail is available.
201
+ - when NOT to use: Do not use as the first fallback for closed profiles; use `send_inmail_closed`.
202
+
203
+ ### InMail (Closed Profile)
204
+
205
+ - type: `send_inmail_closed`
206
+ - displayName: `InMail (Closed Profile)`
207
+ - category: LinkedIn Actions
208
+ - inputs: required `linkedinUrl`, `subject`, and `message`.
209
+ - outputs: paid InMail status and accept wait state.
210
+ - when to use: Use when the prospect is not open-profile and paid credits are intended.
211
+ - when NOT to use: Do not use when the outreach path should avoid paid InMail credits.
212
+
213
+ ### DM
214
+
215
+ - type: `send_dm`
216
+ - displayName: `DM`
217
+ - category: LinkedIn Actions
218
+ - inputs: required `linkedinUrl` and `message`.
219
+ - outputs: DM send status and reply wait state.
220
+ - when to use: Use only after the prospect is already connected.
221
+ - when NOT to use: Do not use for cold prospects who require invite or InMail first.
222
+
223
+ ### View Profile
224
+
225
+ - type: `view_profile`
226
+ - displayName: `View Profile`
227
+ - category: LinkedIn Actions
228
+ - inputs: required `linkedinUrl`.
229
+ - outputs: profile-view action status.
230
+ - when to use: Use as a warm-up action before outreach.
231
+ - when NOT to use: Do not use as a substitute for enrichment; it does not return profile data.
232
+
233
+ ### React & Comment
234
+
235
+ - type: `react_and_comment`
236
+ - displayName: `React & Comment`
237
+ - category: LinkedIn Actions
238
+ - inputs: required post URL as `linkedinUrl`, required `message`, optional `reactionType`.
239
+ - outputs: reaction/comment action status.
240
+ - when to use: Use when the table has a specific LinkedIn post and approved comment text.
241
+ - when NOT to use: Do not use with profile URLs; it expects a post URL.
242
+
243
+ ### Wait
244
+
245
+ - type: `wait`
246
+ - displayName: `Wait`
247
+ - category: LinkedIn Actions
248
+ - inputs: none; duration lives in config.
249
+ - outputs: scheduled/deferred wait state.
250
+ - when to use: Use to pause a sequence between actions.
251
+ - when NOT to use: Do not force-run waits during verification; pass the column id in `skipColumnIds`.
252
+
253
+ ## Generation
254
+
255
+ ### Generate Message
256
+
257
+ - type: `generate_message`
258
+ - displayName: `Generate Message`
259
+ - category: Generation
260
+ - inputs: required `campaignOfferId`, required `enrichedProspectId`, optional `bypassCache`.
261
+ - canonical wiring: use the campaign-backed table's campaign offer id for
262
+ `campaignOfferId`, and map `enrichedProspectId` from Enrich Prospect's
263
+ root `id` output field, not from the whole HTTP result object.
264
+ - outputs: generated message fields from the locked built-in flow.
265
+ - when to use: Use when the table is attached to a campaign offer and needs the production message-generation flow.
266
+ - when NOT to use: Do not use for ad hoc text summarization; use `ai_column`.
267
+
268
+ ## Data & Logic
269
+
270
+ ### AI Column
271
+
272
+ - type: `ai_column`
273
+ - displayName: `AI Column`
274
+ - category: Data & Logic
275
+ - inputs: prompt templates in `config.aiConfig.userPrompt`; no row input schema.
276
+ - outputs: configured `outputFields`, defaulting to `response`.
277
+ - when to use: Use as an escape hatch for custom research, summarization, or classification that does not deserve a dedicated column type.
278
+ - when NOT to use: Do not use where a deterministic or first-party typed column exists.
279
+
280
+ ### Checkbox
281
+
282
+ - type: `checkbox`
283
+ - displayName: `Checkbox`
284
+ - category: Data & Logic
285
+ - inputs: none by default; can map from another source value.
286
+ - outputs: boolean value.
287
+ - when to use: Use for explicit pass/fail markers or manual review state.
288
+ - when NOT to use: Do not use to execute logic that should be reproducible in `formula`.
289
+
290
+ ### Formula
291
+
292
+ - type: `formula`
293
+ - displayName: `Formula`
294
+ - category: Data & Logic
295
+ - inputs: required `expression`.
296
+ - outputs: evaluated expression result.
297
+ - when to use: Use for deterministic transformations of existing row values.
298
+ - when NOT to use: Do not use for external calls or AI judgment.
299
+
300
+ ### HTTP Request
301
+
302
+ - type: `http_request`
303
+ - displayName: `HTTP Request`
304
+ - category: Data & Logic
305
+ - inputs: required `method`, required `endpoint`, optional `headers`, optional `body`.
306
+ - outputs: HTTP status, response body, and metadata; Enrich Prospect also returns root `id` as the EnrichedProspect id.
307
+ - when to use: Use for REST API calls, including the canonical "Enrich Prospect" preset at `/api/v4/enrich-prospect`.
308
+ - when NOT to use: Do not use when a first-party typed column already handles the action.
309
+
310
+ ### Text
311
+
312
+ - type: `text`
313
+ - displayName: `Text`
314
+ - category: Data & Logic
315
+ - inputs: none; user, import, or formula-derived value supplies content.
316
+ - outputs: string value.
317
+ - when to use: Use for static text fields, labels, notes, URLs that are not the canonical LinkedIn URL, or intermediate values.
318
+ - when NOT to use: Do not use as a typed action or enrichment column.