@hyperstar/mcp 0.1.6 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -24
- package/dist/auth/cli-auth-client.js +0 -1
- package/dist/auth/cli-auth-state.js +0 -1
- package/dist/auth/local-callback.js +0 -1
- package/dist/auth/pkce.js +0 -1
- package/dist/bulk-email-guidance.js +0 -1
- package/dist/bulk-email-inputs.d.ts +254 -0
- package/dist/bulk-email-inputs.js +168 -0
- package/dist/bulk-email-tool-body.d.ts +6 -0
- package/dist/bulk-email-tool-body.js +37 -0
- package/dist/campaign-creator-selection.js +0 -1
- package/dist/cli.js +2 -6
- package/dist/config.js +15 -2
- package/dist/discovery.d.ts +6 -0
- package/dist/discovery.js +62 -0
- package/dist/http.js +0 -1
- package/dist/index.js +0 -1
- package/dist/package-metadata.d.ts +2 -0
- package/dist/package-metadata.js +12 -0
- package/dist/schemas.js +0 -1
- package/dist/search-result-projection.d.ts +3 -1
- package/dist/search-result-projection.js +33 -3
- package/dist/server.js +7 -2
- package/dist/tool-descriptions.d.ts +19 -0
- package/dist/tool-descriptions.js +19 -0
- package/dist/tool-guidance.d.ts +10 -0
- package/dist/tool-guidance.js +82 -0
- package/dist/tool-http-helpers.js +0 -1
- package/dist/tool-inputs.d.ts +324 -95
- package/dist/tool-inputs.js +87 -92
- package/dist/tool-result.js +0 -1
- package/dist/tools.js +34 -52
- package/dist/workflow-content.d.ts +43 -0
- package/dist/workflow-content.js +153 -0
- package/dist/workspaces.d.ts +1 -1
- package/dist/workspaces.js +12 -45
- package/package.json +25 -2
- package/dist/auth/cli-auth-client.js.map +0 -1
- package/dist/auth/cli-auth-state.js.map +0 -1
- package/dist/auth/local-callback.js.map +0 -1
- package/dist/auth/pkce.js.map +0 -1
- package/dist/bulk-email-guidance.js.map +0 -1
- package/dist/campaign-creator-selection.js.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/http.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/schemas.js.map +0 -1
- package/dist/search-result-projection.js.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/tool-http-helpers.js.map +0 -1
- package/dist/tool-inputs.js.map +0 -1
- package/dist/tool-result.js.map +0 -1
- package/dist/tools.js.map +0 -1
- package/dist/workspaces.js.map +0 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ CLI login.
|
|
|
7
7
|
|
|
8
8
|
## Install
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Run the MCP server directly from npm:
|
|
11
11
|
|
|
12
12
|
```sh
|
|
13
13
|
npx -y --package @hyperstar/mcp hyperstar-mcp
|
|
@@ -22,6 +22,13 @@ Because the package exposes multiple binaries, use the explicit
|
|
|
22
22
|
`--package @hyperstar/mcp hyperstar-mcp` form instead of bare
|
|
23
23
|
`npx -y @hyperstar/mcp` in MCP client configs.
|
|
24
24
|
|
|
25
|
+
If a client spawns through an environment that loses npm's temporary `.bin`
|
|
26
|
+
path, use the equivalent `npm exec` form:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
npm exec --yes --package @hyperstar/mcp -- hyperstar-mcp
|
|
30
|
+
```
|
|
31
|
+
|
|
25
32
|
For a one-off browser login without a global install:
|
|
26
33
|
|
|
27
34
|
```sh
|
|
@@ -30,16 +37,16 @@ npx -y --package @hyperstar/mcp hyperstar workspaces list --json
|
|
|
30
37
|
npx -y --package @hyperstar/mcp hyperstar workspaces use org_123
|
|
31
38
|
```
|
|
32
39
|
|
|
33
|
-
|
|
40
|
+
For unreleased local package testing, pack from the package directory and use
|
|
41
|
+
the filename printed by `npm pack`:
|
|
34
42
|
|
|
35
43
|
```sh
|
|
36
44
|
cd projects/hyperstar-mcp
|
|
37
|
-
npm pack --
|
|
38
|
-
|
|
39
|
-
npx -y --package
|
|
40
|
-
npx -y --package
|
|
41
|
-
npx -y --package
|
|
42
|
-
npx -y --package ./hyperstar-mcp-0.1.0.tgz hyperstar workspaces use org_123
|
|
45
|
+
TARBALL=$(npm pack --silent)
|
|
46
|
+
npx -y --package "./$TARBALL" hyperstar-mcp
|
|
47
|
+
npx -y --package "./$TARBALL" hyperstar login
|
|
48
|
+
npx -y --package "./$TARBALL" hyperstar workspaces list --json
|
|
49
|
+
npx -y --package "./$TARBALL" hyperstar workspaces use org_123
|
|
43
50
|
```
|
|
44
51
|
|
|
45
52
|
The first public scoped publish must use public access. This package sets
|
|
@@ -48,8 +55,9 @@ credentials are configured.
|
|
|
48
55
|
|
|
49
56
|
## MCP client config
|
|
50
57
|
|
|
51
|
-
Service-account auth is the simplest non-interactive setup.
|
|
52
|
-
|
|
58
|
+
Service-account auth is the simplest non-interactive setup. For production,
|
|
59
|
+
configure only the service-account API key and use the package's default
|
|
60
|
+
Hyperstar Product API base URL:
|
|
53
61
|
|
|
54
62
|
```json
|
|
55
63
|
{
|
|
@@ -58,7 +66,6 @@ server with a Hyperstar Product API base URL and service-account API key:
|
|
|
58
66
|
"command": "npx",
|
|
59
67
|
"args": ["-y", "--package", "@hyperstar/mcp", "hyperstar-mcp"],
|
|
60
68
|
"env": {
|
|
61
|
-
"HYPERSTAR_API_BASE_URL": "https://api.hyperstar.example",
|
|
62
69
|
"HYPERSTAR_API_KEY": "hstar_test_public-prefix.secret"
|
|
63
70
|
}
|
|
64
71
|
}
|
|
@@ -78,11 +85,7 @@ login state created by the `hyperstar` CLI:
|
|
|
78
85
|
"mcpServers": {
|
|
79
86
|
"hyperstar": {
|
|
80
87
|
"command": "npx",
|
|
81
|
-
"args": ["-y", "--package", "@hyperstar/mcp", "hyperstar-mcp"]
|
|
82
|
-
"env": {
|
|
83
|
-
"HYPERSTAR_API_BASE_URL": "https://autopilot.dev.hyper-star.org",
|
|
84
|
-
"HYPERSTAR_APP_BASE_URL": "https://app.dev.hyper-star.org"
|
|
85
|
-
}
|
|
88
|
+
"args": ["-y", "--package", "@hyperstar/mcp", "hyperstar-mcp"]
|
|
86
89
|
}
|
|
87
90
|
}
|
|
88
91
|
}
|
|
@@ -94,13 +97,15 @@ a workspace with `hyperstar workspaces use <organization_id>` or use the MCP
|
|
|
94
97
|
`list_workspaces` and `select_workspace` tools. Service-account mode is already
|
|
95
98
|
workspace-scoped, so `get_hyperstar_workflow_guide` omits `select_workspace`
|
|
96
99
|
when `HYPERSTAR_API_KEY` is used. For non-production login, set matching
|
|
97
|
-
`HYPERSTAR_API_BASE_URL` and `HYPERSTAR_APP_BASE_URL
|
|
98
|
-
|
|
99
|
-
provide an explicit app base URL. `HYPERSTAR_API_KEY` takes precedence over local
|
|
100
|
-
CLI auth when both are present.
|
|
100
|
+
`HYPERSTAR_API_BASE_URL` and `HYPERSTAR_APP_BASE_URL` explicitly.
|
|
101
|
+
`HYPERSTAR_API_KEY` takes precedence over local CLI auth when both are present.
|
|
101
102
|
|
|
102
103
|
## Tools
|
|
103
104
|
|
|
105
|
+
Agents should start by reading `get_hyperstar_workflow_guide` or the MCP
|
|
106
|
+
resources/prompts listed below. Tool responses include `agent_guidance` and,
|
|
107
|
+
where the next step is deterministic, `next_tool` and `next_arguments`.
|
|
108
|
+
|
|
104
109
|
- `hyperstar_whoami`
|
|
105
110
|
- `list_workspaces`
|
|
106
111
|
- `select_workspace`
|
|
@@ -119,6 +124,22 @@ CLI auth when both are present.
|
|
|
119
124
|
- `update_inbox_thread_state`
|
|
120
125
|
- `send_inbox_reply`
|
|
121
126
|
|
|
127
|
+
## Resources and prompts
|
|
128
|
+
|
|
129
|
+
The server exposes static workflow guides as MCP resources:
|
|
130
|
+
|
|
131
|
+
- `hyperstar://guide/headless-workflow`
|
|
132
|
+
- `hyperstar://guide/search-to-campaign`
|
|
133
|
+
- `hyperstar://guide/bulk-email-safety`
|
|
134
|
+
- `hyperstar://guide/inbox`
|
|
135
|
+
|
|
136
|
+
It also exposes matching prompts:
|
|
137
|
+
|
|
138
|
+
- `hyperstar_headless_workflow`
|
|
139
|
+
- `hyperstar_search_to_campaign`
|
|
140
|
+
- `hyperstar_bulk_email_safety`
|
|
141
|
+
- `hyperstar_inbox_workflow`
|
|
142
|
+
|
|
122
143
|
## Development
|
|
123
144
|
|
|
124
145
|
```sh
|
|
@@ -144,11 +165,23 @@ Search creators:
|
|
|
144
165
|
}
|
|
145
166
|
```
|
|
146
167
|
|
|
168
|
+
Common search filters are supplied as a structured JSON object. Useful fields
|
|
169
|
+
include `follower_range` as `{ "min": 1000, "max": 100000 }`,
|
|
170
|
+
`avg_engagement_rate`, `avg_views`, `has_email`, `email_contactability`,
|
|
171
|
+
`is_verified`, `has_tiktok_shop`, `creator_gender`, `creator_language`,
|
|
172
|
+
`category_1`, Instagram `category_name`, `gmv`, and `gpm`; `gmv` and `gpm` are
|
|
173
|
+
TikTok-only. Put broad niches and countries in `query` / `region` unless a
|
|
174
|
+
named structured filter applies. Use `sort_by` for `relevance`,
|
|
175
|
+
`follower_count`, `engagement_rate`, `avg_views`, `views_growth_rate`, `gmv`, or
|
|
176
|
+
`gpm`.
|
|
177
|
+
|
|
147
178
|
Search tools return compact creator summaries by default so agents do not load
|
|
148
179
|
full profile payloads into context. Use `get_search_results` with
|
|
149
180
|
`detail_level: "full"` only when a page of raw creator rows is explicitly
|
|
150
181
|
needed. Bulk actions such as `save_search_results_to_campaign` use `search_id`
|
|
151
|
-
server-side and do not require the agent to materialize every creator.
|
|
182
|
+
server-side and do not require the agent to materialize every creator. The
|
|
183
|
+
search response includes `agent_guidance` and `next_tools` so an unfamiliar
|
|
184
|
+
agent can continue without knowing the UI flow.
|
|
152
185
|
|
|
153
186
|
List or create a campaign before saving creators:
|
|
154
187
|
|
|
@@ -186,9 +219,32 @@ Save search results to a campaign roster:
|
|
|
186
219
|
}
|
|
187
220
|
```
|
|
188
221
|
|
|
222
|
+
Check recipient readiness before any bulk send:
|
|
223
|
+
|
|
224
|
+
```json
|
|
225
|
+
{
|
|
226
|
+
"tool": "check_bulk_email_readiness",
|
|
227
|
+
"arguments": {
|
|
228
|
+
"campaign_id": 123,
|
|
229
|
+
"recipient_target": {
|
|
230
|
+
"type": "ids",
|
|
231
|
+
"campaign_creator_ids": [7, 8]
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
For filtered campaign roster sends, use `recipient_target.type: "selection"`
|
|
238
|
+
and pass `campaign_creator_selection`. The selection must include at least one
|
|
239
|
+
narrowing filter such as `workflow_filter: "email_not_sent"`, `platform`,
|
|
240
|
+
`source_type`, `search`, or `has_video`; empty selections,
|
|
241
|
+
`workflow_filter: "all"` by itself, and exclusions-only selections are
|
|
242
|
+
rejected.
|
|
243
|
+
|
|
189
244
|
Start a bulk email job. This performs a real send. The response includes the
|
|
190
245
|
queued job fields plus `next_tool: "get_bulk_email_job"` and `next_arguments`
|
|
191
|
-
so agents know how to check progress
|
|
246
|
+
so agents know how to check progress. Only call this after readiness has passed
|
|
247
|
+
and the user has authorized the send:
|
|
192
248
|
|
|
193
249
|
```json
|
|
194
250
|
{
|
|
@@ -197,8 +253,12 @@ so agents know how to check progress:
|
|
|
197
253
|
"campaign_id": 123,
|
|
198
254
|
"subject": "Partnership idea",
|
|
199
255
|
"body_text": "Hi, we would like to introduce our new campaign.",
|
|
200
|
-
"
|
|
201
|
-
|
|
256
|
+
"recipient_target": {
|
|
257
|
+
"type": "ids",
|
|
258
|
+
"campaign_creator_ids": [7, 8]
|
|
259
|
+
},
|
|
260
|
+
"idempotency_key": "campaign-123-intro-2026-07-09",
|
|
261
|
+
"send_confirmation": "user_authorized"
|
|
202
262
|
}
|
|
203
263
|
}
|
|
204
264
|
```
|
package/dist/auth/pkce.js
CHANGED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const EmailSubjectSchema: z.ZodString;
|
|
3
|
+
export declare const IdempotencyKeySchema: z.ZodString;
|
|
4
|
+
declare const CampaignCreatorSelectionSchema: z.ZodObject<{
|
|
5
|
+
workflow_filter: z.ZodOptional<z.ZodEnum<{
|
|
6
|
+
all: "all";
|
|
7
|
+
email: "email";
|
|
8
|
+
email_not_sent: "email_not_sent";
|
|
9
|
+
email_sent: "email_sent";
|
|
10
|
+
replied: "replied";
|
|
11
|
+
negotiating: "negotiating";
|
|
12
|
+
rejected_hold: "rejected_hold";
|
|
13
|
+
rejected: "rejected";
|
|
14
|
+
hold: "hold";
|
|
15
|
+
contract: "contract";
|
|
16
|
+
contracted: "contracted";
|
|
17
|
+
content: "content";
|
|
18
|
+
draft: "draft";
|
|
19
|
+
final_approved: "final_approved";
|
|
20
|
+
posted: "posted";
|
|
21
|
+
}>>;
|
|
22
|
+
outreach_stage: z.ZodOptional<z.ZodString>;
|
|
23
|
+
platform: z.ZodOptional<z.ZodEnum<{
|
|
24
|
+
tiktok: "tiktok";
|
|
25
|
+
instagram: "instagram";
|
|
26
|
+
}>>;
|
|
27
|
+
country: z.ZodOptional<z.ZodString>;
|
|
28
|
+
has_video: z.ZodOptional<z.ZodBoolean>;
|
|
29
|
+
source_type: z.ZodOptional<z.ZodEnum<{
|
|
30
|
+
saved_list: "saved_list";
|
|
31
|
+
file_upload: "file_upload";
|
|
32
|
+
manual_add: "manual_add";
|
|
33
|
+
form_submission: "form_submission";
|
|
34
|
+
discovery_search: "discovery_search";
|
|
35
|
+
}>>;
|
|
36
|
+
search: z.ZodOptional<z.ZodString>;
|
|
37
|
+
excluded_ids: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
38
|
+
}, z.core.$strict>;
|
|
39
|
+
export type CampaignCreatorSelectionInput = z.infer<typeof CampaignCreatorSelectionSchema>;
|
|
40
|
+
export declare const CheckBulkEmailReadinessInputSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
41
|
+
campaign_id: z.ZodNumber;
|
|
42
|
+
campaign_creator_ids: z.ZodArray<z.ZodNumber>;
|
|
43
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
44
|
+
campaign_id: z.ZodNumber;
|
|
45
|
+
campaign_creator_selection: z.ZodObject<{
|
|
46
|
+
workflow_filter: z.ZodOptional<z.ZodEnum<{
|
|
47
|
+
all: "all";
|
|
48
|
+
email: "email";
|
|
49
|
+
email_not_sent: "email_not_sent";
|
|
50
|
+
email_sent: "email_sent";
|
|
51
|
+
replied: "replied";
|
|
52
|
+
negotiating: "negotiating";
|
|
53
|
+
rejected_hold: "rejected_hold";
|
|
54
|
+
rejected: "rejected";
|
|
55
|
+
hold: "hold";
|
|
56
|
+
contract: "contract";
|
|
57
|
+
contracted: "contracted";
|
|
58
|
+
content: "content";
|
|
59
|
+
draft: "draft";
|
|
60
|
+
final_approved: "final_approved";
|
|
61
|
+
posted: "posted";
|
|
62
|
+
}>>;
|
|
63
|
+
outreach_stage: z.ZodOptional<z.ZodString>;
|
|
64
|
+
platform: z.ZodOptional<z.ZodEnum<{
|
|
65
|
+
tiktok: "tiktok";
|
|
66
|
+
instagram: "instagram";
|
|
67
|
+
}>>;
|
|
68
|
+
country: z.ZodOptional<z.ZodString>;
|
|
69
|
+
has_video: z.ZodOptional<z.ZodBoolean>;
|
|
70
|
+
source_type: z.ZodOptional<z.ZodEnum<{
|
|
71
|
+
saved_list: "saved_list";
|
|
72
|
+
file_upload: "file_upload";
|
|
73
|
+
manual_add: "manual_add";
|
|
74
|
+
form_submission: "form_submission";
|
|
75
|
+
discovery_search: "discovery_search";
|
|
76
|
+
}>>;
|
|
77
|
+
search: z.ZodOptional<z.ZodString>;
|
|
78
|
+
excluded_ids: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
79
|
+
}, z.core.$strict>;
|
|
80
|
+
}, z.core.$strict>]>;
|
|
81
|
+
export declare const CheckBulkEmailReadinessDiscoveryInputSchema: z.ZodObject<{
|
|
82
|
+
campaign_id: z.ZodNumber;
|
|
83
|
+
recipient_target: z.ZodUnion<readonly [z.ZodObject<{
|
|
84
|
+
type: z.ZodLiteral<"ids">;
|
|
85
|
+
campaign_creator_ids: z.ZodArray<z.ZodNumber>;
|
|
86
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
87
|
+
type: z.ZodLiteral<"selection">;
|
|
88
|
+
campaign_creator_selection: z.ZodObject<{
|
|
89
|
+
workflow_filter: z.ZodOptional<z.ZodEnum<{
|
|
90
|
+
all: "all";
|
|
91
|
+
email: "email";
|
|
92
|
+
email_not_sent: "email_not_sent";
|
|
93
|
+
email_sent: "email_sent";
|
|
94
|
+
replied: "replied";
|
|
95
|
+
negotiating: "negotiating";
|
|
96
|
+
rejected_hold: "rejected_hold";
|
|
97
|
+
rejected: "rejected";
|
|
98
|
+
hold: "hold";
|
|
99
|
+
contract: "contract";
|
|
100
|
+
contracted: "contracted";
|
|
101
|
+
content: "content";
|
|
102
|
+
draft: "draft";
|
|
103
|
+
final_approved: "final_approved";
|
|
104
|
+
posted: "posted";
|
|
105
|
+
}>>;
|
|
106
|
+
outreach_stage: z.ZodOptional<z.ZodString>;
|
|
107
|
+
platform: z.ZodOptional<z.ZodEnum<{
|
|
108
|
+
tiktok: "tiktok";
|
|
109
|
+
instagram: "instagram";
|
|
110
|
+
}>>;
|
|
111
|
+
country: z.ZodOptional<z.ZodString>;
|
|
112
|
+
has_video: z.ZodOptional<z.ZodBoolean>;
|
|
113
|
+
source_type: z.ZodOptional<z.ZodEnum<{
|
|
114
|
+
saved_list: "saved_list";
|
|
115
|
+
file_upload: "file_upload";
|
|
116
|
+
manual_add: "manual_add";
|
|
117
|
+
form_submission: "form_submission";
|
|
118
|
+
discovery_search: "discovery_search";
|
|
119
|
+
}>>;
|
|
120
|
+
search: z.ZodOptional<z.ZodString>;
|
|
121
|
+
excluded_ids: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
122
|
+
}, z.core.$strict>;
|
|
123
|
+
}, z.core.$strict>]>;
|
|
124
|
+
}, z.core.$strict>;
|
|
125
|
+
export declare const StartBulkEmailInputSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
126
|
+
campaign_id: z.ZodNumber;
|
|
127
|
+
subject: z.ZodString;
|
|
128
|
+
body_text: z.ZodString;
|
|
129
|
+
from_email: z.ZodOptional<z.ZodString>;
|
|
130
|
+
attachments: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
131
|
+
form_id: z.ZodOptional<z.ZodNumber>;
|
|
132
|
+
form_language: z.ZodOptional<z.ZodEnum<{
|
|
133
|
+
en: "en";
|
|
134
|
+
ko: "ko";
|
|
135
|
+
jp: "jp";
|
|
136
|
+
}>>;
|
|
137
|
+
idempotency_key: z.ZodString;
|
|
138
|
+
send_confirmation: z.ZodLiteral<"user_authorized">;
|
|
139
|
+
campaign_creator_ids: z.ZodArray<z.ZodNumber>;
|
|
140
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
141
|
+
campaign_id: z.ZodNumber;
|
|
142
|
+
subject: z.ZodString;
|
|
143
|
+
body_text: z.ZodString;
|
|
144
|
+
from_email: z.ZodOptional<z.ZodString>;
|
|
145
|
+
attachments: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
146
|
+
form_id: z.ZodOptional<z.ZodNumber>;
|
|
147
|
+
form_language: z.ZodOptional<z.ZodEnum<{
|
|
148
|
+
en: "en";
|
|
149
|
+
ko: "ko";
|
|
150
|
+
jp: "jp";
|
|
151
|
+
}>>;
|
|
152
|
+
idempotency_key: z.ZodString;
|
|
153
|
+
send_confirmation: z.ZodLiteral<"user_authorized">;
|
|
154
|
+
campaign_creator_selection: z.ZodObject<{
|
|
155
|
+
workflow_filter: z.ZodOptional<z.ZodEnum<{
|
|
156
|
+
all: "all";
|
|
157
|
+
email: "email";
|
|
158
|
+
email_not_sent: "email_not_sent";
|
|
159
|
+
email_sent: "email_sent";
|
|
160
|
+
replied: "replied";
|
|
161
|
+
negotiating: "negotiating";
|
|
162
|
+
rejected_hold: "rejected_hold";
|
|
163
|
+
rejected: "rejected";
|
|
164
|
+
hold: "hold";
|
|
165
|
+
contract: "contract";
|
|
166
|
+
contracted: "contracted";
|
|
167
|
+
content: "content";
|
|
168
|
+
draft: "draft";
|
|
169
|
+
final_approved: "final_approved";
|
|
170
|
+
posted: "posted";
|
|
171
|
+
}>>;
|
|
172
|
+
outreach_stage: z.ZodOptional<z.ZodString>;
|
|
173
|
+
platform: z.ZodOptional<z.ZodEnum<{
|
|
174
|
+
tiktok: "tiktok";
|
|
175
|
+
instagram: "instagram";
|
|
176
|
+
}>>;
|
|
177
|
+
country: z.ZodOptional<z.ZodString>;
|
|
178
|
+
has_video: z.ZodOptional<z.ZodBoolean>;
|
|
179
|
+
source_type: z.ZodOptional<z.ZodEnum<{
|
|
180
|
+
saved_list: "saved_list";
|
|
181
|
+
file_upload: "file_upload";
|
|
182
|
+
manual_add: "manual_add";
|
|
183
|
+
form_submission: "form_submission";
|
|
184
|
+
discovery_search: "discovery_search";
|
|
185
|
+
}>>;
|
|
186
|
+
search: z.ZodOptional<z.ZodString>;
|
|
187
|
+
excluded_ids: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
188
|
+
}, z.core.$strict>;
|
|
189
|
+
}, z.core.$strict>]>;
|
|
190
|
+
export declare const StartBulkEmailDiscoveryInputSchema: z.ZodObject<{
|
|
191
|
+
campaign_id: z.ZodNumber;
|
|
192
|
+
subject: z.ZodString;
|
|
193
|
+
body_text: z.ZodString;
|
|
194
|
+
from_email: z.ZodOptional<z.ZodString>;
|
|
195
|
+
attachments: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
196
|
+
form_id: z.ZodOptional<z.ZodNumber>;
|
|
197
|
+
form_language: z.ZodOptional<z.ZodEnum<{
|
|
198
|
+
en: "en";
|
|
199
|
+
ko: "ko";
|
|
200
|
+
jp: "jp";
|
|
201
|
+
}>>;
|
|
202
|
+
idempotency_key: z.ZodString;
|
|
203
|
+
send_confirmation: z.ZodLiteral<"user_authorized">;
|
|
204
|
+
recipient_target: z.ZodUnion<readonly [z.ZodObject<{
|
|
205
|
+
type: z.ZodLiteral<"ids">;
|
|
206
|
+
campaign_creator_ids: z.ZodArray<z.ZodNumber>;
|
|
207
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
208
|
+
type: z.ZodLiteral<"selection">;
|
|
209
|
+
campaign_creator_selection: z.ZodObject<{
|
|
210
|
+
workflow_filter: z.ZodOptional<z.ZodEnum<{
|
|
211
|
+
all: "all";
|
|
212
|
+
email: "email";
|
|
213
|
+
email_not_sent: "email_not_sent";
|
|
214
|
+
email_sent: "email_sent";
|
|
215
|
+
replied: "replied";
|
|
216
|
+
negotiating: "negotiating";
|
|
217
|
+
rejected_hold: "rejected_hold";
|
|
218
|
+
rejected: "rejected";
|
|
219
|
+
hold: "hold";
|
|
220
|
+
contract: "contract";
|
|
221
|
+
contracted: "contracted";
|
|
222
|
+
content: "content";
|
|
223
|
+
draft: "draft";
|
|
224
|
+
final_approved: "final_approved";
|
|
225
|
+
posted: "posted";
|
|
226
|
+
}>>;
|
|
227
|
+
outreach_stage: z.ZodOptional<z.ZodString>;
|
|
228
|
+
platform: z.ZodOptional<z.ZodEnum<{
|
|
229
|
+
tiktok: "tiktok";
|
|
230
|
+
instagram: "instagram";
|
|
231
|
+
}>>;
|
|
232
|
+
country: z.ZodOptional<z.ZodString>;
|
|
233
|
+
has_video: z.ZodOptional<z.ZodBoolean>;
|
|
234
|
+
source_type: z.ZodOptional<z.ZodEnum<{
|
|
235
|
+
saved_list: "saved_list";
|
|
236
|
+
file_upload: "file_upload";
|
|
237
|
+
manual_add: "manual_add";
|
|
238
|
+
form_submission: "form_submission";
|
|
239
|
+
discovery_search: "discovery_search";
|
|
240
|
+
}>>;
|
|
241
|
+
search: z.ZodOptional<z.ZodString>;
|
|
242
|
+
excluded_ids: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
243
|
+
}, z.core.$strict>;
|
|
244
|
+
}, z.core.$strict>]>;
|
|
245
|
+
}, z.core.$strict>;
|
|
246
|
+
export type CheckBulkEmailReadinessInput = z.infer<typeof CheckBulkEmailReadinessInputSchema>;
|
|
247
|
+
export type StartBulkEmailInput = z.infer<typeof StartBulkEmailInputSchema>;
|
|
248
|
+
type CheckBulkEmailReadinessDiscoveryInput = z.infer<typeof CheckBulkEmailReadinessDiscoveryInputSchema>;
|
|
249
|
+
type StartBulkEmailDiscoveryInput = z.infer<typeof StartBulkEmailDiscoveryInputSchema>;
|
|
250
|
+
/** Convert the MCP-discoverable recipient target into the Product API shape. */
|
|
251
|
+
export declare function normalizeCheckBulkEmailReadinessInput(input: CheckBulkEmailReadinessDiscoveryInput): CheckBulkEmailReadinessInput;
|
|
252
|
+
/** Convert the MCP-discoverable send target into the Product API shape. */
|
|
253
|
+
export declare function normalizeStartBulkEmailInput(input: StartBulkEmailDiscoveryInput): StartBulkEmailInput;
|
|
254
|
+
export {};
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const EmailSubjectSchema = z.string().trim().min(1).max(500);
|
|
3
|
+
const HeaderValueSchema = z
|
|
4
|
+
.string()
|
|
5
|
+
.trim()
|
|
6
|
+
.regex(/^[\x21-\x7e]+$/, {
|
|
7
|
+
message: "value contains unsupported header characters",
|
|
8
|
+
});
|
|
9
|
+
export const IdempotencyKeySchema = HeaderValueSchema.min(1).max(128);
|
|
10
|
+
const SendConfirmationSchema = z.literal("user_authorized");
|
|
11
|
+
const CampaignCreatorWorkflowFilterSchema = z.enum([
|
|
12
|
+
"all",
|
|
13
|
+
"email",
|
|
14
|
+
"email_not_sent",
|
|
15
|
+
"email_sent",
|
|
16
|
+
"replied",
|
|
17
|
+
"negotiating",
|
|
18
|
+
"rejected_hold",
|
|
19
|
+
"rejected",
|
|
20
|
+
"hold",
|
|
21
|
+
"contract",
|
|
22
|
+
"contracted",
|
|
23
|
+
"content",
|
|
24
|
+
"draft",
|
|
25
|
+
"final_approved",
|
|
26
|
+
"posted",
|
|
27
|
+
]);
|
|
28
|
+
const PositiveIdListSchema = z.array(z.number().int().positive()).min(1);
|
|
29
|
+
const CampaignCreatorSelectionSchema = z
|
|
30
|
+
.object({
|
|
31
|
+
workflow_filter: CampaignCreatorWorkflowFilterSchema.optional(),
|
|
32
|
+
outreach_stage: z.string().trim().min(1).optional(),
|
|
33
|
+
platform: z.enum(["tiktok", "instagram"]).optional(),
|
|
34
|
+
country: z.string().trim().min(1).optional(),
|
|
35
|
+
has_video: z.boolean().optional(),
|
|
36
|
+
source_type: z
|
|
37
|
+
.enum([
|
|
38
|
+
"saved_list",
|
|
39
|
+
"file_upload",
|
|
40
|
+
"manual_add",
|
|
41
|
+
"form_submission",
|
|
42
|
+
"discovery_search",
|
|
43
|
+
])
|
|
44
|
+
.optional(),
|
|
45
|
+
search: z.string().trim().min(1).optional(),
|
|
46
|
+
excluded_ids: z.array(z.number().int().positive()).optional(),
|
|
47
|
+
})
|
|
48
|
+
.strict()
|
|
49
|
+
.superRefine((value, context) => {
|
|
50
|
+
const hasNarrowingFilter = (value.workflow_filter !== undefined &&
|
|
51
|
+
value.workflow_filter !== "all") ||
|
|
52
|
+
value.outreach_stage !== undefined ||
|
|
53
|
+
value.platform !== undefined ||
|
|
54
|
+
value.country !== undefined ||
|
|
55
|
+
value.has_video !== undefined ||
|
|
56
|
+
value.source_type !== undefined ||
|
|
57
|
+
value.search !== undefined;
|
|
58
|
+
if (!hasNarrowingFilter) {
|
|
59
|
+
context.addIssue({
|
|
60
|
+
code: "custom",
|
|
61
|
+
message: "campaign_creator_selection must include a narrowing filter; use campaign_creator_ids for exact rows",
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
const CampaignRecipientIdsTargetSchema = z
|
|
66
|
+
.object({
|
|
67
|
+
campaign_creator_ids: PositiveIdListSchema,
|
|
68
|
+
})
|
|
69
|
+
.strict();
|
|
70
|
+
const CampaignRecipientSelectionTargetSchema = z
|
|
71
|
+
.object({
|
|
72
|
+
campaign_creator_selection: CampaignCreatorSelectionSchema,
|
|
73
|
+
})
|
|
74
|
+
.strict();
|
|
75
|
+
const CampaignRecipientTargetSchema = z.union([
|
|
76
|
+
z
|
|
77
|
+
.object({
|
|
78
|
+
type: z.literal("ids"),
|
|
79
|
+
campaign_creator_ids: PositiveIdListSchema.describe("Exact campaign creator row IDs selected from list_campaign_creators."),
|
|
80
|
+
})
|
|
81
|
+
.strict(),
|
|
82
|
+
z
|
|
83
|
+
.object({
|
|
84
|
+
type: z.literal("selection"),
|
|
85
|
+
campaign_creator_selection: CampaignCreatorSelectionSchema.describe("Narrowed campaign roster selection, such as workflow_filter: email_not_sent."),
|
|
86
|
+
})
|
|
87
|
+
.strict(),
|
|
88
|
+
]);
|
|
89
|
+
function validateFormLanguage(value, context) {
|
|
90
|
+
if (value.form_language !== undefined && value.form_id === undefined) {
|
|
91
|
+
context.addIssue({
|
|
92
|
+
code: "custom",
|
|
93
|
+
message: "form_id is required when form_language is provided",
|
|
94
|
+
path: ["form_id"],
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const CheckBulkEmailReadinessBaseSchema = z.object({
|
|
99
|
+
campaign_id: z.number().int().positive(),
|
|
100
|
+
});
|
|
101
|
+
export const CheckBulkEmailReadinessInputSchema = z.union([
|
|
102
|
+
CheckBulkEmailReadinessBaseSchema.merge(CampaignRecipientIdsTargetSchema),
|
|
103
|
+
CheckBulkEmailReadinessBaseSchema.merge(CampaignRecipientSelectionTargetSchema),
|
|
104
|
+
]);
|
|
105
|
+
export const CheckBulkEmailReadinessDiscoveryInputSchema = CheckBulkEmailReadinessBaseSchema.extend({
|
|
106
|
+
recipient_target: CampaignRecipientTargetSchema,
|
|
107
|
+
}).strict();
|
|
108
|
+
const StartBulkEmailBaseSchema = z
|
|
109
|
+
.object({
|
|
110
|
+
campaign_id: z.number().int().positive(),
|
|
111
|
+
subject: EmailSubjectSchema,
|
|
112
|
+
body_text: z.string().trim().min(1),
|
|
113
|
+
from_email: z.string().trim().min(1).optional(),
|
|
114
|
+
attachments: z.array(z.string().trim().min(1)).optional(),
|
|
115
|
+
form_id: z.number().int().positive().optional(),
|
|
116
|
+
form_language: z.enum(["en", "ko", "jp"]).optional(),
|
|
117
|
+
idempotency_key: IdempotencyKeySchema,
|
|
118
|
+
send_confirmation: SendConfirmationSchema,
|
|
119
|
+
})
|
|
120
|
+
.strict();
|
|
121
|
+
export const StartBulkEmailInputSchema = z
|
|
122
|
+
.union([
|
|
123
|
+
StartBulkEmailBaseSchema.merge(CampaignRecipientIdsTargetSchema),
|
|
124
|
+
StartBulkEmailBaseSchema.merge(CampaignRecipientSelectionTargetSchema),
|
|
125
|
+
])
|
|
126
|
+
.superRefine(validateFormLanguage);
|
|
127
|
+
export const StartBulkEmailDiscoveryInputSchema = StartBulkEmailBaseSchema.extend({
|
|
128
|
+
recipient_target: CampaignRecipientTargetSchema,
|
|
129
|
+
})
|
|
130
|
+
.strict()
|
|
131
|
+
.superRefine(validateFormLanguage);
|
|
132
|
+
/** Convert the MCP-discoverable recipient target into the Product API shape. */
|
|
133
|
+
export function normalizeCheckBulkEmailReadinessInput(input) {
|
|
134
|
+
if (input.recipient_target.type === "ids") {
|
|
135
|
+
return {
|
|
136
|
+
campaign_id: input.campaign_id,
|
|
137
|
+
campaign_creator_ids: input.recipient_target.campaign_creator_ids,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
campaign_id: input.campaign_id,
|
|
142
|
+
campaign_creator_selection: input.recipient_target.campaign_creator_selection,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/** Convert the MCP-discoverable send target into the Product API shape. */
|
|
146
|
+
export function normalizeStartBulkEmailInput(input) {
|
|
147
|
+
const base = {
|
|
148
|
+
campaign_id: input.campaign_id,
|
|
149
|
+
subject: input.subject,
|
|
150
|
+
body_text: input.body_text,
|
|
151
|
+
from_email: input.from_email,
|
|
152
|
+
attachments: input.attachments,
|
|
153
|
+
form_id: input.form_id,
|
|
154
|
+
form_language: input.form_language,
|
|
155
|
+
idempotency_key: input.idempotency_key,
|
|
156
|
+
send_confirmation: input.send_confirmation,
|
|
157
|
+
};
|
|
158
|
+
if (input.recipient_target.type === "ids") {
|
|
159
|
+
return {
|
|
160
|
+
...base,
|
|
161
|
+
campaign_creator_ids: input.recipient_target.campaign_creator_ids,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
...base,
|
|
166
|
+
campaign_creator_selection: input.recipient_target.campaign_creator_selection,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { JsonObject } from "./http.js";
|
|
2
|
+
import type { CheckBulkEmailReadinessInput, StartBulkEmailInput } from "./tool-inputs.js";
|
|
3
|
+
/** Build the campaign bulk-email readiness request body. */
|
|
4
|
+
export declare function readinessRequestBody(input: CheckBulkEmailReadinessInput): JsonObject;
|
|
5
|
+
/** Build the campaign bulk-email job request body. */
|
|
6
|
+
export declare function startBulkEmailRequestBody(input: StartBulkEmailInput): JsonObject;
|