@facelessad/mcp 2.0.0 → 2.1.1
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 +1 -1
- package/SKILL.md +7 -1
- package/index.js +6 -6
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ with your account. Same twelve tools, same fields.
|
|
|
49
49
|
| `facelessad_list_brand_kits` | Your brands and their ids (for `brand_kit_id`) |
|
|
50
50
|
| `facelessad_voices` | Curated voice pool |
|
|
51
51
|
| `facelessad_list_parts` | The parts of a finished video and how each is fixed |
|
|
52
|
-
| `facelessad_regenerate_part` | Redo ONE part (clip, image card or
|
|
52
|
+
| `facelessad_regenerate_part` | Redo ONE part (clip, image card, graphics block, or a `bg-N` AI photo background) |
|
|
53
53
|
| `facelessad_regenerate_video` | Rebuild the whole video as a new id |
|
|
54
54
|
| `facelessad_render_settings` | Re-render a finished video with new caption/audio settings |
|
|
55
55
|
|
package/SKILL.md
CHANGED
|
@@ -165,7 +165,7 @@ Video Banner is a silent loop: no voice, no script, no music, no SFX.
|
|
|
165
165
|
|
|
166
166
|
`voiceover_text` makes the narration spoken **word-for-word** — the AI script
|
|
167
167
|
writer is skipped and not charged. The word limit follows the duration: 15 s
|
|
168
|
-
fits ~
|
|
168
|
+
fits ~45 words, 30 s ~80, 50 s ~130. Over the limit is a clear error, never a
|
|
169
169
|
silent trim, so count before sending. Not on music-video (its script is sung)
|
|
170
170
|
or video-banner.
|
|
171
171
|
|
|
@@ -212,6 +212,11 @@ Which field a part takes:
|
|
|
212
212
|
text-animation, video-banner, and the graphics layer of product-showcase):
|
|
213
213
|
a plain-language change like "make the headline say Faster onboarding". The
|
|
214
214
|
server applies it to the block's current code — you never send code.
|
|
215
|
+
- `prompt` on a `bg-N` part — AI photo backgrounds (styles flagged
|
|
216
|
+
`genBg:true` in `facelessad_list_tools`): describe the new backdrop, e.g.
|
|
217
|
+
"warm sunset gradient with soft haze". The graphics stay untouched,
|
|
218
|
+
text/logos/UI are always excluded automatically, and the video re-renders.
|
|
219
|
+
6 credits per image.
|
|
215
220
|
|
|
216
221
|
Product Showcase lists two parts per scene: the product clip (`prompt`) and
|
|
217
222
|
the graphics over it (`instruction`). Continuous videos chain their clips and
|
|
@@ -302,6 +307,7 @@ Every tool returns the API's own JSON; on failure `{ok:false, error, code}`.
|
|
|
302
307
|
- `card_needs_image_prompt` — a card needs `image_prompt`, not `prompt`.
|
|
303
308
|
- `webhook_limit` / `webhook_not_found` / `invalid_url` — webhook endpoints: five per account; no such id; or a URL we cannot reach. (You manage these through the API or CLI, not through a tool here.)
|
|
304
309
|
- `graphics_needs_instruction` / `instruction_not_supported` — graphics blocks take `instruction`, and only they do.
|
|
310
|
+
- `bg_needs_prompt` — a `bg-N` background image is regenerated with `prompt` describing the backdrop.
|
|
305
311
|
|
|
306
312
|
## Rules for agents
|
|
307
313
|
|
package/index.js
CHANGED
|
@@ -82,7 +82,7 @@ const server = new McpServer({ name: 'facelessad', version: '2.0.0' });
|
|
|
82
82
|
|
|
83
83
|
server.tool(
|
|
84
84
|
'facelessad_list_tools',
|
|
85
|
-
'The FacelessAd registry: available video tools with their styles, ad structures, hook formulas, duration bounds and aspect ratios. Call this FIRST to learn valid ids — style/structure/hook ids passed to other tools are validated against this list.',
|
|
85
|
+
'The FacelessAd registry: available video tools with their styles, ad structures, hook formulas, duration bounds and aspect ratios. Call this FIRST to learn valid ids — style/structure/hook ids passed to other tools are validated against this list. Styles flagged genBg:true generate an AI photo background behind every part (+6 credits per part in the estimate); their finished videos expose bg-N parts for background regeneration.',
|
|
86
86
|
{},
|
|
87
87
|
async () => result(await api('GET', '/api/v1/tools'))
|
|
88
88
|
);
|
|
@@ -200,7 +200,7 @@ const createShape = {
|
|
|
200
200
|
badge: z.enum(['none', 'random_face']).optional().describe('video-banner only: "random_face" picks the same AI face the app offers. Ignored when badge_image_url is set.'),
|
|
201
201
|
photo_query: z.string().optional().describe('video-banner only: steer the automatic background photo search, e.g. "nordic office"'),
|
|
202
202
|
// 1.4.0 (§799): oma käsikirjoitus + visuaalinen ohjaus.
|
|
203
|
-
voiceover_text: z.string().optional().describe('Your own voice-over, spoken WORD-FOR-WORD — the AI script writer is skipped entirely (and not charged). Word limit follows duration: 15s fits
|
|
203
|
+
voiceover_text: z.string().optional().describe('Your own voice-over, spoken WORD-FOR-WORD — the AI script writer is skipped entirely (and not charged). Word limit follows duration: 15s fits 45 words, 30s fits 80, 50s fits 130; over the limit is an error, never a silent trim. Single narrator only; not on music-video (its script is sung lyrics) or video-banner (no narration).'),
|
|
204
204
|
visual_direction: z.string().optional().describe('How the video should LOOK and what happens visually (max 600 chars): setting, emotional arc, recurring motif, when the product appears. Steers the storyboard — the art style still comes from style/custom_style.'),
|
|
205
205
|
hook_text: z.string().optional().describe('Your own first-frame hook card text, used as-is (max 120 chars). Omitted, it is derived from the script.'),
|
|
206
206
|
// 1.5.0 (§806): tekstitysten ulkoasu.
|
|
@@ -226,7 +226,7 @@ server.tool(
|
|
|
226
226
|
|
|
227
227
|
server.tool(
|
|
228
228
|
'facelessad_get_video',
|
|
229
|
-
'Status of one video by id. When finished, includes a download URL valid ~
|
|
229
|
+
'Status of one video by id. When finished, includes a download URL valid ~24 hours — call again for a fresh one rather than storing it.',
|
|
230
230
|
{ id: z.union([z.string(), z.number()]).describe('The id returned by facelessad_create_video') },
|
|
231
231
|
async ({ id }) => result(await api('GET', '/api/v1/videos/' + encodeURIComponent(String(id))))
|
|
232
232
|
);
|
|
@@ -253,18 +253,18 @@ server.tool(
|
|
|
253
253
|
|
|
254
254
|
server.tool(
|
|
255
255
|
'facelessad_list_parts',
|
|
256
|
-
'List the parts of a finished video so one of them can be regenerated. Model A / image-card videos return scene clips and image cards (uid, type, duration, current motion prompt, image_prompt, preview links). Graphics tools return graphics_block parts (gfx-0, gfx-1, ...). Product Showcase returns BOTH layers per scene: the product clip and the graphics block over it. Each part says whether it is regenerable and which field it needs (regenerate_requires).',
|
|
256
|
+
'List the parts of a finished video so one of them can be regenerated. Model A / image-card videos return scene clips and image cards (uid, type, duration, current motion prompt, image_prompt, preview links). Graphics tools return graphics_block parts (gfx-0, gfx-1, ...) — and on background-image styles (styles flagged genBg in facelessad_list_tools) ALSO a background_image layer per part (bg-0, bg-1, ...), regenerated with prompt. Product Showcase returns BOTH layers per scene: the product clip and the graphics block over it. Each part says whether it is regenerable and which field it needs (regenerate_requires).',
|
|
257
257
|
{ video_id: z.string().describe('Video id from facelessad_create_video') },
|
|
258
258
|
async ({ video_id }) => result(await api('GET', '/api/v1/videos/' + encodeURIComponent(video_id) + '/parts'))
|
|
259
259
|
);
|
|
260
260
|
|
|
261
261
|
server.tool(
|
|
262
262
|
'facelessad_regenerate_part',
|
|
263
|
-
'Write prompt as CONCRETE PHYSICAL MOTION of characters and objects, never camera moves ("she sets the mug down and exhales" works, "slow zoom in on the product" does not — the pipeline forbids camera movement). Regenerate or edit ONE part of a finished video — far cheaper than rebuilding it. prompt = new take of a scene clip from the same start image. image_prompt = a new image first (scene clips and image cards; required for cards), then the clip/card is rebuilt from it. instruction = plain-language edit of a graphics block ("make the headline say Faster onboarding") applied server-side to the block\'s current code — you never send or receive code. The whole video re-renders automatically and the new file replaces the video url; the previous render stays as an asset version. Works within 7 days of the build. Poll facelessad_get_video for the new url.',
|
|
263
|
+
'Write prompt as CONCRETE PHYSICAL MOTION of characters and objects, never camera moves ("she sets the mug down and exhales" works, "slow zoom in on the product" does not — the pipeline forbids camera movement). Regenerate or edit ONE part of a finished video — far cheaper than rebuilding it. prompt = new take of a scene clip from the same start image. image_prompt = a new image first (scene clips and image cards; required for cards), then the clip/card is rebuilt from it. instruction = plain-language edit of a graphics block ("make the headline say Faster onboarding") applied server-side to the block\'s current code — you never send or receive code. For bg-N background images (genBg styles) pass prompt describing the new backdrop ("warm sunset gradient, soft haze") — the graphics stay untouched, text/logos/UI are always excluded automatically, and it bills 6 credits per image. The whole video re-renders automatically and the new file replaces the video url; the previous render stays as an asset version. Works within 7 days of the build. Poll facelessad_get_video for the new url.',
|
|
264
264
|
{
|
|
265
265
|
video_id: z.string().describe('Video id'),
|
|
266
266
|
part_uid: z.string().describe('Part uid from facelessad_list_parts (must be regenerable:true)'),
|
|
267
|
-
prompt: z.string().optional().describe('New motion prompt for a scene clip (max 900 chars)'),
|
|
267
|
+
prompt: z.string().optional().describe('New motion prompt for a scene clip, OR for a bg-N part the new backdrop description (max 900 chars)'),
|
|
268
268
|
image_prompt: z.string().optional().describe('New image description (max 900 chars) — required for image cards'),
|
|
269
269
|
instruction: z.string().optional().describe('Plain-language change for a graphics_block part (max 900 chars)'),
|
|
270
270
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@facelessad/mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "FacelessAd as MCP tools \u2014 let your AI assistant create faceless video ads (Claude Desktop, Claude Code, Cursor, Windsurf, OpenClaw).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -28,4 +28,4 @@
|
|
|
28
28
|
"ai"
|
|
29
29
|
],
|
|
30
30
|
"homepage": "https://facelessad.com/developers"
|
|
31
|
-
}
|
|
31
|
+
}
|