@hyperstar/mcp 0.1.9 → 0.1.11
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 +52 -34
- 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 -2
- package/dist/config.js +15 -2
- package/dist/discovery.js +0 -1
- 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 +5 -2
- package/dist/tool-descriptions.d.ts +4 -4
- package/dist/tool-descriptions.js +4 -5
- package/dist/tool-guidance.js +24 -7
- package/dist/tool-http-helpers.js +0 -1
- package/dist/tool-inputs.d.ts +324 -131
- package/dist/tool-inputs.js +87 -92
- package/dist/tool-result.js +0 -1
- package/dist/tools.js +11 -31
- package/dist/workflow-content.d.ts +1 -0
- package/dist/workflow-content.js +19 -3
- package/dist/workspaces.d.ts +1 -1
- package/dist/workspaces.js +9 -2
- package/package.json +24 -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/discovery.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-descriptions.js.map +0 -1
- package/dist/tool-guidance.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/workflow-content.js.map +0 -1
- package/dist/workspaces.js.map +0 -1
package/dist/config.js
CHANGED
|
@@ -26,7 +26,14 @@ export function loadConfig(options = process.env) {
|
|
|
26
26
|
if (state === null) {
|
|
27
27
|
throw new Error("Run `hyperstar login` or set HYPERSTAR_API_KEY");
|
|
28
28
|
}
|
|
29
|
-
const
|
|
29
|
+
const stateApiBaseUrl = normalizeBaseUrl(state.apiBaseUrl, "stored Hyperstar auth API base URL");
|
|
30
|
+
const rawCliApiBaseUrl = env.HYPERSTAR_API_BASE_URL?.trim();
|
|
31
|
+
const cliApiBaseUrl = normalizeBaseUrl(rawCliApiBaseUrl === undefined || rawCliApiBaseUrl.length === 0
|
|
32
|
+
? stateApiBaseUrl
|
|
33
|
+
: rawCliApiBaseUrl, "HYPERSTAR_API_BASE_URL");
|
|
34
|
+
if (rawCliApiBaseUrl !== undefined && rawCliApiBaseUrl.length > 0) {
|
|
35
|
+
assertCliApiBaseUrlMatchesState(cliApiBaseUrl, stateApiBaseUrl);
|
|
36
|
+
}
|
|
30
37
|
const cliAppBaseUrl = normalizeBaseUrl(env.HYPERSTAR_APP_BASE_URL?.trim() ?? state.appBaseUrl, "HYPERSTAR_APP_BASE_URL");
|
|
31
38
|
const client = createCliAuthClient({
|
|
32
39
|
apiBaseUrl: cliApiBaseUrl,
|
|
@@ -79,6 +86,13 @@ export function redactSecret(value) {
|
|
|
79
86
|
function isValidApiKeyHeaderValue(value) {
|
|
80
87
|
return /^[\x21-\x7e]+$/.test(value);
|
|
81
88
|
}
|
|
89
|
+
/** Refuse to send persisted CLI tokens to a different API base URL. */
|
|
90
|
+
function assertCliApiBaseUrlMatchesState(requestedApiBaseUrl, stateApiBaseUrl) {
|
|
91
|
+
if (requestedApiBaseUrl === stateApiBaseUrl) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
throw new Error("Run `hyperstar login` again before changing HYPERSTAR_API_BASE_URL");
|
|
95
|
+
}
|
|
82
96
|
/** Normalize an env-provided base URL. */
|
|
83
97
|
export function normalizeBaseUrl(rawBaseUrl, envName) {
|
|
84
98
|
let parsed;
|
|
@@ -98,4 +112,3 @@ export function normalizeBaseUrl(rawBaseUrl, envName) {
|
|
|
98
112
|
}
|
|
99
113
|
return parsed.toString().replace(/\/+$/, "");
|
|
100
114
|
}
|
|
101
|
-
//# sourceMappingURL=config.js.map
|
package/dist/discovery.js
CHANGED
package/dist/http.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { JsonObjectSchema } from "./schemas.js";
|
|
3
|
+
/** Read package metadata from the package root at runtime. */
|
|
4
|
+
export function packageVersion() {
|
|
5
|
+
const raw = readFileSync(new URL("../package.json", import.meta.url), "utf8");
|
|
6
|
+
const metadata = JsonObjectSchema.parse(JSON.parse(raw));
|
|
7
|
+
const version = metadata.version;
|
|
8
|
+
if (typeof version !== "string" || version.trim().length === 0) {
|
|
9
|
+
throw new Error("package.json version is missing");
|
|
10
|
+
}
|
|
11
|
+
return version;
|
|
12
|
+
}
|
package/dist/schemas.js
CHANGED
|
@@ -66,4 +66,3 @@ export const BulkEmailJobResponseSchema = JsonObjectSchema;
|
|
|
66
66
|
export const InboxThreadPageResponseSchema = JsonObjectSchema;
|
|
67
67
|
export const InboxAggregatesResponseSchema = JsonObjectSchema;
|
|
68
68
|
export const InboxWorkspaceStateResponseSchema = JsonObjectSchema;
|
|
69
|
-
//# sourceMappingURL=schemas.js.map
|
|
@@ -7,4 +7,6 @@ export type SearchResultPage = {
|
|
|
7
7
|
readonly limit: number;
|
|
8
8
|
};
|
|
9
9
|
/** Project search results to the requested MCP-facing detail level. */
|
|
10
|
-
export declare function projectSearchResultPage(page: SearchResultPage, detailLevel: SearchResultDetailLevel
|
|
10
|
+
export declare function projectSearchResultPage(page: SearchResultPage, detailLevel: SearchResultDetailLevel, searchId?: string, options?: {
|
|
11
|
+
readonly deterministicNextPage?: boolean;
|
|
12
|
+
}): JsonObject;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { compactJsonObject } from "./tool-http-helpers.js";
|
|
2
2
|
/** Project search results to the requested MCP-facing detail level. */
|
|
3
|
-
export function projectSearchResultPage(page, detailLevel) {
|
|
3
|
+
export function projectSearchResultPage(page, detailLevel, searchId, options = {}) {
|
|
4
|
+
const pagination = paginationGuidance(page, searchId, options);
|
|
4
5
|
if (detailLevel === "full") {
|
|
5
|
-
return { ...page, detail_level: detailLevel };
|
|
6
|
+
return { ...page, detail_level: detailLevel, ...pagination };
|
|
6
7
|
}
|
|
7
8
|
return {
|
|
8
9
|
...page,
|
|
9
10
|
creators: page.creators.map(compactCreatorSummary),
|
|
10
11
|
detail_level: detailLevel,
|
|
12
|
+
...pagination,
|
|
11
13
|
};
|
|
12
14
|
}
|
|
13
15
|
/** Return a compact creator summary suitable for model context. */
|
|
@@ -71,4 +73,32 @@ function stringArrayValue(value) {
|
|
|
71
73
|
}
|
|
72
74
|
return value;
|
|
73
75
|
}
|
|
74
|
-
|
|
76
|
+
function paginationGuidance(page, searchId, options) {
|
|
77
|
+
const nextOffset = page.offset + page.limit;
|
|
78
|
+
const hasMore = nextOffset < page.total;
|
|
79
|
+
const includeDeterministicNext = options.deterministicNextPage !== false &&
|
|
80
|
+
hasMore &&
|
|
81
|
+
searchId !== undefined;
|
|
82
|
+
return compactJsonObject([
|
|
83
|
+
["has_more", hasMore],
|
|
84
|
+
["next_offset", hasMore ? nextOffset : undefined],
|
|
85
|
+
[
|
|
86
|
+
"agent_guidance",
|
|
87
|
+
searchId === undefined
|
|
88
|
+
? undefined
|
|
89
|
+
: "Use search_id server-side for campaign import. Page with get_search_results only when the user needs more creator summaries; do not load every creator into context.",
|
|
90
|
+
],
|
|
91
|
+
["next_tool", includeDeterministicNext ? "get_search_results" : undefined],
|
|
92
|
+
[
|
|
93
|
+
"next_arguments",
|
|
94
|
+
includeDeterministicNext
|
|
95
|
+
? {
|
|
96
|
+
search_id: searchId,
|
|
97
|
+
offset: nextOffset,
|
|
98
|
+
limit: page.limit,
|
|
99
|
+
detail_level: "summary",
|
|
100
|
+
}
|
|
101
|
+
: undefined,
|
|
102
|
+
],
|
|
103
|
+
]);
|
|
104
|
+
}
|
package/dist/server.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import { registerHyperstarDiscovery } from "./discovery.js";
|
|
3
3
|
import { createHyperstarClient } from "./http.js";
|
|
4
|
+
import { packageVersion } from "./package-metadata.js";
|
|
4
5
|
import { registerHyperstarTools } from "./tools.js";
|
|
5
6
|
/** Create the Hyperstar MCP server and register HTTP-backed workflow tools. */
|
|
6
7
|
export function createHyperstarMcpServer(config) {
|
|
7
|
-
const server = new McpServer({
|
|
8
|
+
const server = new McpServer({
|
|
9
|
+
name: "hyperstar",
|
|
10
|
+
version: packageVersion(),
|
|
11
|
+
});
|
|
8
12
|
registerHyperstarDiscovery(server, { apiBaseUrl: config.apiBaseUrl });
|
|
9
13
|
registerHyperstarTools(server, createHyperstarClient({ config }), config.authMode === "cli"
|
|
10
14
|
? { workspaceSelection: config.workspaceSelection }
|
|
11
15
|
: {});
|
|
12
16
|
return server;
|
|
13
17
|
}
|
|
14
|
-
//# sourceMappingURL=server.js.map
|
|
@@ -3,17 +3,17 @@ export declare const TOOL_DESCRIPTIONS: {
|
|
|
3
3
|
readonly listWorkspaces: "List Hyperstar workspaces available to the current auth session. In local browser CLI auth, call select_workspace next when a workspace is not selected.";
|
|
4
4
|
readonly selectWorkspace: "Persist the Hyperstar workspace selected for CLI-authenticated tools. Call hyperstar_whoami next to confirm scope.";
|
|
5
5
|
readonly workflowGuide: "Return the recommended Hyperstar workflow sequence, discovery resources, and send-safety notes.";
|
|
6
|
-
readonly searchCreators: "Create a creator search and return the first page as compact creator summaries. Use search_id with save_search_results_to_campaign; request detail_level full only when raw rows are needed.";
|
|
6
|
+
readonly searchCreators: "Create a creator search and return the first page as compact creator summaries. Filters use structured keys such as follower_range, avg_engagement_rate, avg_views, has_email, email_contactability, creator_language, category_1, category_name, gmv, and gpm. Put broad niches in query unless a platform-specific category field applies. Use search_id with save_search_results_to_campaign; request detail_level full only when raw rows are needed.";
|
|
7
7
|
readonly getSearchResults: "Page through an existing creator search. Defaults to compact creator summaries; use detail_level full only for raw detail-on-demand pages.";
|
|
8
8
|
readonly listCampaigns: "List campaigns in the authenticated workspace so agents can choose a campaign_id before saving search results.";
|
|
9
9
|
readonly createCampaign: "Create a campaign in the authenticated workspace. Use the returned campaign id with save_search_results_to_campaign.";
|
|
10
10
|
readonly saveSearchResultsToCampaign: "Save selected or top-ranked creator search results to a campaign roster server-side using search_id.";
|
|
11
11
|
readonly listCampaignCreators: "List creators saved on a campaign roster. Call check_bulk_email_readiness before any bulk-email send.";
|
|
12
|
-
readonly checkBulkEmailReadiness: "The final dry-run gate before bulk email.
|
|
13
|
-
readonly startBulkEmail: "REAL SEND: start a campaign bulk-email job
|
|
12
|
+
readonly checkBulkEmailReadiness: "The final dry-run gate before bulk email. Requires recipient_target with exact IDs or a narrowed selection, checks those selected recipients, and returns sendability guidance.";
|
|
13
|
+
readonly startBulkEmail: "REAL SEND: start a campaign bulk-email job after readiness has passed and the user authorized sending. Requires recipient_target, an explicit idempotency key, and send_confirmation: \"user_authorized\".";
|
|
14
14
|
readonly getBulkEmailJob: "Read campaign bulk-email job status after start_bulk_email returns a job_id.";
|
|
15
15
|
readonly listInboxThreads: "List Hyperstar inbox threads with filters for triage before reading or replying.";
|
|
16
16
|
readonly getInboxAggregates: "Read aggregate counts for Hyperstar inbox filters to summarize inbox state.";
|
|
17
17
|
readonly updateInboxThreadState: "Archive, snooze, star, or set read state for one inbox thread without sending a message.";
|
|
18
|
-
readonly sendInboxReply: "REAL SEND: send one reply to a Hyperstar inbox thread with an explicit idempotency key.";
|
|
18
|
+
readonly sendInboxReply: "REAL SEND: send one user-authorized reply to a Hyperstar inbox thread with an explicit idempotency key.";
|
|
19
19
|
};
|
|
@@ -3,18 +3,17 @@ export const TOOL_DESCRIPTIONS = {
|
|
|
3
3
|
listWorkspaces: "List Hyperstar workspaces available to the current auth session. In local browser CLI auth, call select_workspace next when a workspace is not selected.",
|
|
4
4
|
selectWorkspace: "Persist the Hyperstar workspace selected for CLI-authenticated tools. Call hyperstar_whoami next to confirm scope.",
|
|
5
5
|
workflowGuide: "Return the recommended Hyperstar workflow sequence, discovery resources, and send-safety notes.",
|
|
6
|
-
searchCreators: "Create a creator search and return the first page as compact creator summaries. Use search_id with save_search_results_to_campaign; request detail_level full only when raw rows are needed.",
|
|
6
|
+
searchCreators: "Create a creator search and return the first page as compact creator summaries. Filters use structured keys such as follower_range, avg_engagement_rate, avg_views, has_email, email_contactability, creator_language, category_1, category_name, gmv, and gpm. Put broad niches in query unless a platform-specific category field applies. Use search_id with save_search_results_to_campaign; request detail_level full only when raw rows are needed.",
|
|
7
7
|
getSearchResults: "Page through an existing creator search. Defaults to compact creator summaries; use detail_level full only for raw detail-on-demand pages.",
|
|
8
8
|
listCampaigns: "List campaigns in the authenticated workspace so agents can choose a campaign_id before saving search results.",
|
|
9
9
|
createCampaign: "Create a campaign in the authenticated workspace. Use the returned campaign id with save_search_results_to_campaign.",
|
|
10
10
|
saveSearchResultsToCampaign: "Save selected or top-ranked creator search results to a campaign roster server-side using search_id.",
|
|
11
11
|
listCampaignCreators: "List creators saved on a campaign roster. Call check_bulk_email_readiness before any bulk-email send.",
|
|
12
|
-
checkBulkEmailReadiness: "The final dry-run gate before bulk email.
|
|
13
|
-
startBulkEmail:
|
|
12
|
+
checkBulkEmailReadiness: "The final dry-run gate before bulk email. Requires recipient_target with exact IDs or a narrowed selection, checks those selected recipients, and returns sendability guidance.",
|
|
13
|
+
startBulkEmail: 'REAL SEND: start a campaign bulk-email job after readiness has passed and the user authorized sending. Requires recipient_target, an explicit idempotency key, and send_confirmation: "user_authorized".',
|
|
14
14
|
getBulkEmailJob: "Read campaign bulk-email job status after start_bulk_email returns a job_id.",
|
|
15
15
|
listInboxThreads: "List Hyperstar inbox threads with filters for triage before reading or replying.",
|
|
16
16
|
getInboxAggregates: "Read aggregate counts for Hyperstar inbox filters to summarize inbox state.",
|
|
17
17
|
updateInboxThreadState: "Archive, snooze, star, or set read state for one inbox thread without sending a message.",
|
|
18
|
-
sendInboxReply: "REAL SEND: send one reply to a Hyperstar inbox thread with an explicit idempotency key.",
|
|
18
|
+
sendInboxReply: "REAL SEND: send one user-authorized reply to a Hyperstar inbox thread with an explicit idempotency key.",
|
|
19
19
|
};
|
|
20
|
-
//# sourceMappingURL=tool-descriptions.js.map
|
package/dist/tool-guidance.js
CHANGED
|
@@ -27,12 +27,17 @@ export function campaignRosterGuidance(payload, campaignId) {
|
|
|
27
27
|
...payload,
|
|
28
28
|
next_tool: "check_bulk_email_readiness",
|
|
29
29
|
next_arguments: { campaign_id: campaignId },
|
|
30
|
-
|
|
30
|
+
next_required_arguments: ["recipient_target"],
|
|
31
|
+
agent_guidance: "Before any bulk email, call check_bulk_email_readiness with recipient_target set to exact campaign creator IDs or a narrowed selection filter.",
|
|
31
32
|
};
|
|
32
33
|
}
|
|
33
34
|
/** Add send or no-send guidance after the readiness dry run. */
|
|
34
35
|
export function readinessGuidance(payload, input) {
|
|
35
36
|
const sendable = numberValue(payload.sendable);
|
|
37
|
+
const campaignCreatorIds = "campaign_creator_ids" in input ? input.campaign_creator_ids : undefined;
|
|
38
|
+
const campaignCreatorSelection = "campaign_creator_selection" in input
|
|
39
|
+
? input.campaign_creator_selection
|
|
40
|
+
: undefined;
|
|
36
41
|
if (sendable === undefined || sendable <= 0) {
|
|
37
42
|
return {
|
|
38
43
|
...payload,
|
|
@@ -44,14 +49,27 @@ export function readinessGuidance(payload, input) {
|
|
|
44
49
|
next_tool: "start_bulk_email",
|
|
45
50
|
next_arguments: compactJsonObject([
|
|
46
51
|
["campaign_id", input.campaign_id],
|
|
47
|
-
["campaign_creator_ids", input.campaign_creator_ids],
|
|
48
52
|
[
|
|
49
|
-
"
|
|
50
|
-
|
|
53
|
+
"recipient_target",
|
|
54
|
+
recipientTargetArgument(campaignCreatorIds, campaignCreatorSelection),
|
|
51
55
|
],
|
|
52
56
|
]),
|
|
53
|
-
next_required_arguments: [
|
|
54
|
-
|
|
57
|
+
next_required_arguments: [
|
|
58
|
+
"subject",
|
|
59
|
+
"body_text",
|
|
60
|
+
"idempotency_key",
|
|
61
|
+
"send_confirmation",
|
|
62
|
+
],
|
|
63
|
+
agent_guidance: 'Readiness passed. start_bulk_email performs a real send, so only call it after user authorization and after filling subject, body_text, a stable idempotency_key, and send_confirmation: "user_authorized".',
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function recipientTargetArgument(ids, selection) {
|
|
67
|
+
if (ids !== undefined) {
|
|
68
|
+
return { type: "ids", campaign_creator_ids: [...ids] };
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
type: "selection",
|
|
72
|
+
campaign_creator_selection: selectionBody(selection) ?? {},
|
|
55
73
|
};
|
|
56
74
|
}
|
|
57
75
|
function selectionBody(selection) {
|
|
@@ -62,4 +80,3 @@ function numberValue(value) {
|
|
|
62
80
|
? value
|
|
63
81
|
: undefined;
|
|
64
82
|
}
|
|
65
|
-
//# sourceMappingURL=tool-guidance.js.map
|