@jclvsh/dropspace 2.31.0 → 2.33.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.
- package/README.md +56 -47
- package/dist/commands/launches.js +3 -0
- package/dist/commands/personas.js +3 -0
- package/dist/commands/reddit.js +7 -1
- package/dist/server.js +12 -2
- package/dist/tool-policy.d.ts +10 -1
- package/dist/tool-policy.js +22 -1
- package/dist/tools/launches.js +4 -0
- package/dist/tools/reddit.js +1 -1
- package/package.json +1 -1
- package/skills/dropspace/SKILL.md +7 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @jclvsh/dropspace
|
|
2
2
|
|
|
3
|
-
MCP server and CLI for the [Dropspace](https://www.dropspace.dev) API. Lets AI agents (Claude Code, Cursor) and humans manage launches, personas, media generation, boosts, autopilot, recommendations, reddit engagement, platform connections, API keys, and webhooks.
|
|
3
|
+
MCP server and CLI for the [Dropspace](https://www.dropspace.dev) API. Lets AI agents (Claude Code, Cursor) and humans manage launches, personas, media generation, boosts, autopilot, recommendations, reddit engagement, platform connections, API keys, and webhooks. The full tool list, by category, is in the tables below and at https://www.dropspace.dev/docs#mcp-server.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -44,23 +44,23 @@ dropspace launches --help
|
|
|
44
44
|
|
|
45
45
|
### CLI Commands
|
|
46
46
|
|
|
47
|
-
| Group | Commands |
|
|
48
|
-
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
|
49
|
-
| launches | list, create, get, update, delete, publish, retry, generate, retry-content, analytics, batch-analytics, status, delete-post, delete-posts |
|
|
50
|
-
| personas | list, create, get, update, delete, analyze |
|
|
51
|
-
| media | generate, job
|
|
52
|
-
| connections | list |
|
|
53
|
-
| boosts | create, list, get, activate, cancel, performance |
|
|
54
|
-
| reddit | suggest
|
|
55
|
-
| credits | balance, purchase |
|
|
56
|
-
| keys | me, list, create, rename, revoke, rotate |
|
|
57
|
-
| webhooks | list, create, get, update, delete, test, rotate-secret, deliveries |
|
|
58
|
-
| status | dropspace official account connections |
|
|
59
|
-
| usage | plan, limits, and billing period |
|
|
60
|
-
| changelog | machine-readable release history |
|
|
61
|
-
| audience | follower counts + growth per connected account |
|
|
62
|
-
| autopilot | status, configure, review, approve, reject, run, runs |
|
|
63
|
-
| recommendations (recs) | list, apply, dismiss |
|
|
47
|
+
| Group | Commands |
|
|
48
|
+
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
|
49
|
+
| launches | list, create, get, update, delete, publish, retry, generate, retry-content, analytics, batch-analytics, status, delete-post, delete-posts |
|
|
50
|
+
| personas | list, create, get, update, delete, analyze |
|
|
51
|
+
| media | generate, job, library list, library add, library describe, library delete |
|
|
52
|
+
| connections | list |
|
|
53
|
+
| boosts | create, list, get, activate, cancel, performance |
|
|
54
|
+
| reddit | suggest |
|
|
55
|
+
| credits | balance, purchase |
|
|
56
|
+
| keys | me, list, create, rename, revoke, rotate |
|
|
57
|
+
| webhooks | list, create, get, update, delete, test, rotate-secret, deliveries |
|
|
58
|
+
| status | dropspace official account connections |
|
|
59
|
+
| usage | plan, limits, and billing period |
|
|
60
|
+
| changelog | machine-readable release history |
|
|
61
|
+
| audience | follower counts + growth per connected account |
|
|
62
|
+
| autopilot | status, configure, review, approve, reject, run, runs |
|
|
63
|
+
| recommendations (recs) | list, apply, dismiss |
|
|
64
64
|
|
|
65
65
|
## MCP Server Configuration
|
|
66
66
|
|
|
@@ -119,7 +119,7 @@ https://api.dropspace.dev/mcp
|
|
|
119
119
|
|
|
120
120
|
- Transport: MCP streamable HTTP, `POST` only, stateless, JSON responses.
|
|
121
121
|
- Auth: `Authorization: Bearer ds_live_...` (the same API key; its scopes apply).
|
|
122
|
-
- Tools: a subset of this package. API key, webhook, boost, credit, and reddit
|
|
122
|
+
- Tools: a subset of this package. API key, webhook, boost, credit, and reddit tools are only available through the npm package.
|
|
123
123
|
- Every tool is annotated by class: `read` (`readOnlyHint: true`), `write`, or `sensitive` (`destructiveHint: true`: it publishes, schedules, or deletes on a connected platform, or deletes a launch or persona with no restore). The class of each hosted tool is listed at https://www.dropspace.dev/docs#mcp-hosted, and the source of truth is `src/tool-policy.ts`.
|
|
124
124
|
- `create_launch` sends a content-derived `Idempotency-Key`, so a retry after a timeout returns the launch already created instead of creating a second one (the result says so).
|
|
125
125
|
- Each MCP request counts once against the key's rate limit, and each tool call counts once more when it reaches the REST API.
|
|
@@ -163,6 +163,8 @@ Other agents that read skill files can use the same file from `node_modules/@jcl
|
|
|
163
163
|
| `product_description` | string | Yes | Product description |
|
|
164
164
|
| `platforms` | string[] | Yes | Platforms to publish to (1-9) |
|
|
165
165
|
| `product_url` | string | No | Product URL |
|
|
166
|
+
| `track_links` | boolean | No | Swap `product_url` in X, LinkedIn, Facebook, Reddit, and YouTube copy for a tracked link; clicks show as `metrics.tracked_clicks` in analytics |
|
|
167
|
+
| `save_to_library` | boolean | No | Add the launch's uploaded media to the media library so autopilot can post it |
|
|
166
168
|
| `scheduled_date` | string | No | ISO 8601 datetime (15+ min in the future) |
|
|
167
169
|
| `persona_id` | string | No | Persona ID for tone/style |
|
|
168
170
|
| `dropspace_platforms` | string[] | No | Platforms to post via official dropspace accounts |
|
|
@@ -222,24 +224,31 @@ Other agents that read skill files can use the same file from `node_modules/@jcl
|
|
|
222
224
|
|
|
223
225
|
#### `update_persona` Parameters
|
|
224
226
|
|
|
225
|
-
| Parameter | Type
|
|
226
|
-
| ------------------- |
|
|
227
|
-
| `id` | string
|
|
228
|
-
| `name` | string
|
|
229
|
-
| `custom_samples` | array
|
|
230
|
-
| `twitter_samples` | array
|
|
231
|
-
| `reddit_samples` | array
|
|
232
|
-
| `facebook_samples` | array
|
|
233
|
-
| `instagram_samples` | array
|
|
234
|
-
| `tiktok_samples` | array
|
|
235
|
-
| `linkedin_samples` | array
|
|
227
|
+
| Parameter | Type | Required | Description |
|
|
228
|
+
| ------------------- | -------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
229
|
+
| `id` | string | Yes | Persona ID |
|
|
230
|
+
| `name` | string | No | New persona name (1-100 characters) |
|
|
231
|
+
| `custom_samples` | array | No | Custom writing samples (max 50) |
|
|
232
|
+
| `twitter_samples` | array | No | Twitter writing samples (max 50) |
|
|
233
|
+
| `reddit_samples` | array | No | Reddit writing samples (max 50) |
|
|
234
|
+
| `facebook_samples` | array | No | Facebook writing samples (max 50) |
|
|
235
|
+
| `instagram_samples` | array | No | Instagram writing samples (max 50) |
|
|
236
|
+
| `tiktok_samples` | array | No | TikTok writing samples (max 50) |
|
|
237
|
+
| `linkedin_samples` | array | No | LinkedIn writing samples (max 50) |
|
|
238
|
+
| `brand_kit` | object \| null | No | Autopilot slide styling: `text_color`, `outline_color` (#RRGGBB), `logo_url`, `logo_position` (`top-left`, `top-right`, `bottom-left`, `bottom-right`); null clears it |
|
|
236
239
|
|
|
237
240
|
### Media
|
|
238
241
|
|
|
239
|
-
| Tool
|
|
240
|
-
|
|
|
241
|
-
| `generate_media`
|
|
242
|
-
| `get_media_job`
|
|
242
|
+
| Tool | Description |
|
|
243
|
+
| --------------------------- | ----------------------------------------------------------------------------- |
|
|
244
|
+
| `generate_media` | Submit an AI image or video generation job for a launch (returns a job ID) |
|
|
245
|
+
| `get_media_job` | Poll a media generation job's status; returns the result URL when complete |
|
|
246
|
+
| `list_media_library` | List the user's own photos and videos that autopilot can post (stdio only) |
|
|
247
|
+
| `add_to_media_library` | Add photos or videos by public URL, with an optional description (stdio only) |
|
|
248
|
+
| `update_media_library_item` | Set what a library item shows; autopilot chooses media by it (stdio only) |
|
|
249
|
+
| `delete_media_library_item` | Remove an item from the library (stdio only) |
|
|
250
|
+
|
|
251
|
+
`generate_media` takes `use_product_image: true` to build an image from the launch's product page image. The four library tools are not on the hosted endpoint yet.
|
|
243
252
|
|
|
244
253
|
### Connections
|
|
245
254
|
|
|
@@ -249,14 +258,14 @@ Other agents that read skill files can use the same file from `node_modules/@jcl
|
|
|
249
258
|
|
|
250
259
|
### Boosts
|
|
251
260
|
|
|
252
|
-
| Tool | Description
|
|
253
|
-
| ----------------------- |
|
|
254
|
-
| `create_boost` | Create a paid Meta boost
|
|
255
|
-
| `list_boosts` | List all boosts attached to a launch
|
|
256
|
-
| `get_boost` | Get a boost by ID with current performance metrics
|
|
257
|
-
| `activate_boost` | Activate a paused boost — ad spend begins immediately
|
|
258
|
-
| `cancel_boost` | Cancel a boost (deletes the Meta campaign, irreversible)
|
|
259
|
-
| `get_boost_performance` | Fetch latest boost metrics (impressions, clicks, reach, spend)
|
|
261
|
+
| Tool | Description |
|
|
262
|
+
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
263
|
+
| `create_boost` | Create a paid Meta boost (paused): `objective` engagement or traffic (Facebook link posts), optional `max_cpc_cents` cap. Running boosts pause themselves when click-through decays |
|
|
264
|
+
| `list_boosts` | List all boosts attached to a launch |
|
|
265
|
+
| `get_boost` | Get a boost by ID with current performance metrics |
|
|
266
|
+
| `activate_boost` | Activate a paused boost — ad spend begins immediately |
|
|
267
|
+
| `cancel_boost` | Cancel a boost (deletes the Meta campaign, irreversible) |
|
|
268
|
+
| `get_boost_performance` | Fetch latest boost metrics (impressions, clicks, reach, spend) |
|
|
260
269
|
|
|
261
270
|
### Credits
|
|
262
271
|
|
|
@@ -305,10 +314,10 @@ Other agents that read skill files can use the same file from `node_modules/@jcl
|
|
|
305
314
|
|
|
306
315
|
#### `create_webhook` Parameters
|
|
307
316
|
|
|
308
|
-
| Parameter | Type | Required | Description
|
|
309
|
-
| --------- | -------- | -------- |
|
|
310
|
-
| `url` | string | Yes | HTTPS webhook URL
|
|
311
|
-
| `events` | string[] | Yes | Events to subscribe to: `launch.completed`, `launch.failed`, `launch.partial`, `media.ready`, `persona.analyzed`, `post.deleted` |
|
|
317
|
+
| Parameter | Type | Required | Description |
|
|
318
|
+
| --------- | -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
319
|
+
| `url` | string | Yes | Public HTTPS webhook URL. A Slack incoming webhook URL (`https://hooks.slack.com/services/...`) receives readable Slack messages instead of signed JSON |
|
|
320
|
+
| `events` | string[] | Yes | Events to subscribe to: `launch.completed`, `launch.failed`, `launch.partial`, `media.ready`, `persona.analyzed`, `post.deleted`, `recommendation.created`, `connection.expired`, `connection.restored` |
|
|
312
321
|
|
|
313
322
|
#### `update_webhook` Parameters
|
|
314
323
|
|
|
@@ -360,7 +369,7 @@ Counts come from each platform's official API and are cached for 15 minutes. You
|
|
|
360
369
|
| `run_autopilot_now` | Trigger a manual autopilot run immediately (2 per hour) |
|
|
361
370
|
| `list_autopilot_runs` | Recent run history with per-step stats and errors |
|
|
362
371
|
|
|
363
|
-
Autopilot is available on pro and premium plans.
|
|
372
|
+
Autopilot is available on pro and premium plans. `configure_autopilot` takes `media_source` (`ai`, `library`, `mixed`) to post the user's own photos and videos, and `product_image_url` for AI slides built from the real product.
|
|
364
373
|
|
|
365
374
|
### Recommendations
|
|
366
375
|
|
|
@@ -28,6 +28,7 @@ export function registerLaunchCommands(program, client) {
|
|
|
28
28
|
.option("--platforms <list>", "comma-separated platforms", parseList)
|
|
29
29
|
.option("--url <url>", "product URL")
|
|
30
30
|
.option("--track-links", "post the product URL as tracked redirects; clicks show in analytics")
|
|
31
|
+
.option("--save-to-library", "add this launch's uploaded media to your media library for autopilot")
|
|
31
32
|
.option("--schedule <datetime>", "ISO 8601 schedule datetime")
|
|
32
33
|
.option("--persona <id>", "persona ID for tone/style")
|
|
33
34
|
.option("--dropspace-platforms <list>", "platforms for official dropspace accounts", parseList)
|
|
@@ -50,6 +51,8 @@ export function registerLaunchCommands(program, client) {
|
|
|
50
51
|
body.product_url = opts.url;
|
|
51
52
|
if (opts.trackLinks)
|
|
52
53
|
body.track_links = true;
|
|
54
|
+
if (opts.saveToLibrary)
|
|
55
|
+
body.save_to_library = true;
|
|
53
56
|
if (opts.schedule)
|
|
54
57
|
body.scheduled_date = opts.schedule;
|
|
55
58
|
if (opts.persona)
|
|
@@ -56,6 +56,7 @@ export function registerPersonaCommands(program, client) {
|
|
|
56
56
|
.option("--instagram-samples <json>", "instagram writing samples as JSON array")
|
|
57
57
|
.option("--tiktok-samples <json>", "tiktok writing samples as JSON array")
|
|
58
58
|
.option("--linkedin-samples <json>", "linkedin writing samples as JSON array")
|
|
59
|
+
.option("--brand-kit <json>", 'autopilot slide styling, e.g. \'{"text_color":"#FFFFFF","logo_url":"https://...","logo_position":"top-right"}\'; "none" clears it')
|
|
59
60
|
.action(async (id, opts) => {
|
|
60
61
|
try {
|
|
61
62
|
const body = {};
|
|
@@ -75,6 +76,8 @@ export function registerPersonaCommands(program, client) {
|
|
|
75
76
|
body.tiktok_samples = JSON.parse(opts.tiktokSamples);
|
|
76
77
|
if (opts.linkedinSamples)
|
|
77
78
|
body.linkedin_samples = JSON.parse(opts.linkedinSamples);
|
|
79
|
+
if (opts.brandKit)
|
|
80
|
+
body.brand_kit = opts.brandKit === "none" ? null : JSON.parse(opts.brandKit);
|
|
78
81
|
const result = await client.patch(`/personas/${id}`, body);
|
|
79
82
|
formatOutput(result, getFormat(program.opts()));
|
|
80
83
|
}
|
package/dist/commands/reddit.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { formatOutput, handleError, getFormat } from "../cli-utils.js";
|
|
2
|
+
import { REDDIT_ENGAGEMENT_PAUSED } from "../tool-policy.js";
|
|
2
3
|
/**
|
|
3
4
|
* Reddit discovery + engagement CLI — the earn-standing-before-promoting loop:
|
|
4
5
|
* suggest → activate → discover → approve/reject → standing. Requires an api key whose
|
|
@@ -7,7 +8,9 @@ import { formatOutput, handleError, getFormat } from "../cli-utils.js";
|
|
|
7
8
|
export function registerRedditCommands(program, client) {
|
|
8
9
|
const reddit = program
|
|
9
10
|
.command("reddit")
|
|
10
|
-
.description(
|
|
11
|
+
.description(REDDIT_ENGAGEMENT_PAUSED
|
|
12
|
+
? "subreddit discovery"
|
|
13
|
+
: "subreddit discovery + engagement (earn standing before promoting)");
|
|
11
14
|
reddit
|
|
12
15
|
.command("suggest")
|
|
13
16
|
.description("ICP-matched subreddit discovery with per-community standing badges")
|
|
@@ -21,6 +24,9 @@ export function registerRedditCommands(program, client) {
|
|
|
21
24
|
handleError(error);
|
|
22
25
|
}
|
|
23
26
|
});
|
|
27
|
+
// Engagement commands are paused with the API (see REDDIT_ENGAGEMENT_PAUSED).
|
|
28
|
+
if (REDDIT_ENGAGEMENT_PAUSED)
|
|
29
|
+
return;
|
|
24
30
|
reddit
|
|
25
31
|
.command("config")
|
|
26
32
|
.description("read the engagement settings (enabled, caps, gate state, comment voice)")
|
package/dist/server.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import { createPolicyRegistrar } from "./policy.js";
|
|
3
|
-
import { TOOL_POLICY } from "./tool-policy.js";
|
|
3
|
+
import { PAUSED_TOOLS, TOOL_POLICY } from "./tool-policy.js";
|
|
4
4
|
import { registerLaunchTools } from "./tools/launches.js";
|
|
5
5
|
import { registerPersonaTools } from "./tools/personas.js";
|
|
6
6
|
import { registerConnectionTools } from "./tools/connections.js";
|
|
@@ -15,9 +15,19 @@ import { registerAutopilotTools } from "./tools/autopilot.js";
|
|
|
15
15
|
import { registerRecommendationTools } from "./tools/recommendations.js";
|
|
16
16
|
import { registerRedditTools } from "./tools/reddit.js";
|
|
17
17
|
import { registerAudienceTools } from "./tools/audience.js";
|
|
18
|
+
/** Drops tools whose feature is paused before the policy registrar sees them (see PAUSED_TOOLS). */
|
|
19
|
+
function skipPausedTools(registrar) {
|
|
20
|
+
return {
|
|
21
|
+
tool(name, ...rest) {
|
|
22
|
+
if (PAUSED_TOOLS.has(name))
|
|
23
|
+
return;
|
|
24
|
+
return registrar.tool(name, ...rest);
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
18
28
|
export function createDropspaceServer({ client, version, profile }) {
|
|
19
29
|
const server = new McpServer({ name: "dropspace", version });
|
|
20
|
-
const registrar = createPolicyRegistrar(server, TOOL_POLICY, profile);
|
|
30
|
+
const registrar = skipPausedTools(createPolicyRegistrar(server, TOOL_POLICY, profile));
|
|
21
31
|
registerLaunchTools(registrar, client);
|
|
22
32
|
registerPersonaTools(registrar, client);
|
|
23
33
|
registerConnectionTools(registrar, client);
|
package/dist/tool-policy.d.ts
CHANGED
|
@@ -18,8 +18,17 @@ import { type PolicyTable, type ToolClass, type ToolPolicy, type ToolProfile } f
|
|
|
18
18
|
export type { ToolClass, ToolPolicy, ToolProfile };
|
|
19
19
|
export declare const TOOL_CATEGORIES: readonly ["launches", "posts", "personas", "media", "connections", "boosts", "credits", "API keys", "webhooks", "dropspace", "usage", "autopilot", "recommendations", "reddit engagement", "audience"];
|
|
20
20
|
export type ToolCategory = (typeof TOOL_CATEGORIES)[number];
|
|
21
|
+
/**
|
|
22
|
+
* Reddit engagement is paused (dropspace's reddit_engagement_disabled switch, 10/15/2026): the API
|
|
23
|
+
* answers 404 on /reddit/engagement/*, so the package neither serves nor counts these tools, and
|
|
24
|
+
* the CLI drops their commands. Set false, with the switch, to bring them back.
|
|
25
|
+
*/
|
|
26
|
+
export declare const REDDIT_ENGAGEMENT_PAUSED = true;
|
|
27
|
+
/** Tools classified but not served while their feature is paused. */
|
|
28
|
+
export declare const PAUSED_TOOLS: ReadonlySet<string>;
|
|
29
|
+
/** The tools the package serves - every docs count and category list reads this. */
|
|
21
30
|
export declare const TOOL_POLICY: PolicyTable<ToolCategory>;
|
|
22
|
-
export declare const toolPolicy: (name: string) => ToolPolicy<"launches" | "personas" | "connections" | "webhooks" | "usage" | "credits" | "media" | "boosts" | "
|
|
31
|
+
export declare const toolPolicy: (name: string) => ToolPolicy<"launches" | "personas" | "connections" | "webhooks" | "usage" | "credits" | "media" | "boosts" | "audience" | "posts" | "API keys" | "dropspace" | "autopilot" | "recommendations" | "reddit engagement">;
|
|
23
32
|
export declare const isToolEnabled: (name: string, profile: ToolProfile) => boolean;
|
|
24
33
|
export declare const toolAnnotations: (name: string) => {
|
|
25
34
|
readOnlyHint: boolean;
|
package/dist/tool-policy.js
CHANGED
|
@@ -42,7 +42,7 @@ const localOnly = (category, toolClass) => ({
|
|
|
42
42
|
hosted: false,
|
|
43
43
|
category,
|
|
44
44
|
});
|
|
45
|
-
|
|
45
|
+
const FULL_TOOL_POLICY = {
|
|
46
46
|
// launches
|
|
47
47
|
list_launches: hosted("launches", "read"),
|
|
48
48
|
get_launch: hosted("launches", "read"),
|
|
@@ -144,6 +144,27 @@ export const TOOL_POLICY = {
|
|
|
144
144
|
test_webhook: localOnly("webhooks", "write"),
|
|
145
145
|
rotate_webhook_secret: localOnly("webhooks", "sensitive"),
|
|
146
146
|
};
|
|
147
|
+
/**
|
|
148
|
+
* Reddit engagement is paused (dropspace's reddit_engagement_disabled switch, 10/15/2026): the API
|
|
149
|
+
* answers 404 on /reddit/engagement/*, so the package neither serves nor counts these tools, and
|
|
150
|
+
* the CLI drops their commands. Set false, with the switch, to bring them back.
|
|
151
|
+
*/
|
|
152
|
+
export const REDDIT_ENGAGEMENT_PAUSED = true;
|
|
153
|
+
const REDDIT_ENGAGEMENT_TOOLS = [
|
|
154
|
+
"get_engagement_config",
|
|
155
|
+
"get_engagement_standing",
|
|
156
|
+
"list_engagement_comments",
|
|
157
|
+
"update_engagement_config",
|
|
158
|
+
"discover_engagement",
|
|
159
|
+
"reject_engagement_comment",
|
|
160
|
+
"activate_engagement_subreddit",
|
|
161
|
+
"deactivate_engagement_subreddit",
|
|
162
|
+
"approve_engagement_comment",
|
|
163
|
+
];
|
|
164
|
+
/** Tools classified but not served while their feature is paused. */
|
|
165
|
+
export const PAUSED_TOOLS = new Set(REDDIT_ENGAGEMENT_PAUSED ? REDDIT_ENGAGEMENT_TOOLS : []);
|
|
166
|
+
/** The tools the package serves - every docs count and category list reads this. */
|
|
167
|
+
export const TOOL_POLICY = Object.fromEntries(Object.entries(FULL_TOOL_POLICY).filter(([name]) => !PAUSED_TOOLS.has(name)));
|
|
147
168
|
export const toolPolicy = (name) => toolPolicyFor(TOOL_POLICY, name);
|
|
148
169
|
export const isToolEnabled = (name, profile) => isToolEnabledIn(TOOL_POLICY, name, profile);
|
|
149
170
|
export const toolAnnotations = (name) => toolAnnotationsFor(TOOL_POLICY, name);
|
package/dist/tools/launches.js
CHANGED
|
@@ -90,6 +90,10 @@ export function registerLaunchTools(server, client) {
|
|
|
90
90
|
.url()
|
|
91
91
|
.optional()
|
|
92
92
|
.describe("product URL — scraped to generate content; can substitute for product_description"),
|
|
93
|
+
save_to_library: z
|
|
94
|
+
.boolean()
|
|
95
|
+
.optional()
|
|
96
|
+
.describe("add the launch's uploaded media to the user's media library so autopilot can post it"),
|
|
93
97
|
track_links: z
|
|
94
98
|
.boolean()
|
|
95
99
|
.optional()
|
package/dist/tools/reddit.js
CHANGED
|
@@ -59,7 +59,7 @@ export function registerRedditTools(server, client) {
|
|
|
59
59
|
return fail(error);
|
|
60
60
|
}
|
|
61
61
|
});
|
|
62
|
-
server.tool("discover_engagement", "draft helpful comments for ONE of the account's active subreddits (call again to cover more). fills the review queue; posts NOTHING — approval is the separate, rail-gated step. `skipped` names why nothing ran (kill_switch | not_enabled | gate_not_passed).", {}, async () => {
|
|
62
|
+
server.tool("discover_engagement", "draft helpful comments for ONE of the account's active subreddits (call again to cover more). fills the review queue; posts NOTHING — approval is the separate, rail-gated step. `skipped` names why nothing ran (kill_switch | not_enabled | gate_not_passed | account_hidden).", {}, async () => {
|
|
63
63
|
try {
|
|
64
64
|
return ok(await client.post("/reddit/engagement/discover"));
|
|
65
65
|
}
|
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@ Dropspace turns one brief into per-platform posts and publishes them on the user
|
|
|
10
10
|
## Setup
|
|
11
11
|
|
|
12
12
|
- MCP over stdio: `npx -y -p @jclvsh/dropspace dropspace-mcp` with `DROPSPACE_API_KEY=ds_live_...` in the environment. Every tool is available.
|
|
13
|
-
- Hosted MCP: `https://api.dropspace.dev/mcp` (streamable HTTP, POST, `Authorization: Bearer ds_live_...`). Serves a subset: no credits, boosts, API keys, webhooks, or reddit
|
|
13
|
+
- Hosted MCP: `https://api.dropspace.dev/mcp` (streamable HTTP, POST, `Authorization: Bearer ds_live_...`). Serves a subset: no credits, boosts, API keys, webhooks, or reddit tools.
|
|
14
14
|
- CLI: `npx -y @jclvsh/dropspace <command>` (the same key). `dropspace --help` lists commands.
|
|
15
15
|
- No key? The user creates one at https://www.dropspace.dev/settings/api. A key's scopes limit what it can do (`read`, `write`, `generate`, `send`, `admin`); a 403 names the missing scope.
|
|
16
16
|
|
|
@@ -25,6 +25,7 @@ Dropspace turns one brief into per-platform posts and publishes them on the user
|
|
|
25
25
|
1. `create_launch` with `product_url` and/or `product_description` and `platforms`. Dropspace reads the product page and writes copy per platform.
|
|
26
26
|
- Use `platform_contents` or `custom_content` when the user already wrote the copy.
|
|
27
27
|
- `track_links: true` posts the product URL as a tracked redirect on X, LinkedIn, Facebook, Reddit, and YouTube; clicks then appear in analytics. Tell the user their posts will show a dropspace.dev link.
|
|
28
|
+
- `save_to_library: true` adds the launch's uploaded photos and videos to the user's media library, where autopilot can post them.
|
|
28
29
|
- `scheduled_date` (ISO 8601, at least 15 minutes out) schedules it; without one, the launch waits for `publish_launch`.
|
|
29
30
|
2. Review: `get_launch` shows the generated copy per platform. Show it to the user before publishing anything they have not seen. Edit with `update_launch`; regenerate one platform with `retry_launch_content`.
|
|
30
31
|
3. Media (optional): `generate_media` with `type: "image"` and `use_product_image: true` makes an image of the real product from its page; `get_media_job` polls it. Videos are 8-second clips (`type: "video"` or `"script_video"`).
|
|
@@ -35,13 +36,17 @@ Dropspace turns one brief into per-platform posts and publishes them on the user
|
|
|
35
36
|
|
|
36
37
|
- Recommendations: `list_recommendations` after posts have run a day or two; `apply_recommendation` turns one into a draft launch, an autopilot post, or a paused boost. Nothing publishes or spends on apply.
|
|
37
38
|
- Autopilot (pro and premium plans): `get_autopilot`, `configure_autopilot`, `run_autopilot_now`. In review mode it drafts posts for approval: `list_autopilot_review`, `approve_autopilot_draft`, `reject_autopilot_draft`.
|
|
39
|
+
- `media_source`: `ai` (generated slides and video), `library` (only the user's own media), or `mixed` (library first). `product_image_url` makes AI slides show the real product.
|
|
40
|
+
- Media library (stdio server and CLI only): `list_media_library`, `add_to_media_library`, `update_media_library_item`, `delete_media_library_item`. Autopilot chooses items by their description, so describe each one; videos must have one.
|
|
41
|
+
- Brand kit: `update_persona` with `brand_kit` (text and outline colors, a corner logo) styles the image slides autopilot posts as that persona.
|
|
38
42
|
- Audience: `get_audience` for follower counts on Instagram, TikTok, and YouTube.
|
|
43
|
+
- Webhooks: `create_webhook` with a Slack incoming webhook URL (`https://hooks.slack.com/services/...`) posts events to that channel as readable messages.
|
|
39
44
|
|
|
40
45
|
## Spending money - confirm first
|
|
41
46
|
|
|
42
47
|
These cost the user money. Get an explicit yes for the amount before calling them:
|
|
43
48
|
|
|
44
|
-
- `activate_boost` starts real ad spend on the user's Meta ad account. `create_boost` makes it paused; activation is the spend.
|
|
49
|
+
- `activate_boost` starts real ad spend on the user's Meta ad account. `create_boost` makes it paused; activation is the spend. Offer `max_cpc_cents` so the boost pauses itself if clicks get expensive; `objective: "traffic"` needs a Facebook link post.
|
|
45
50
|
- `purchase_credit_pack`.
|
|
46
51
|
|
|
47
52
|
## Errors that need the user
|