@clipwright/mcp-server 0.19.0 → 0.21.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/CHANGELOG.md +55 -0
- package/README.md +25 -4
- package/SKILL.md +39 -3
- package/dist/format.js +10 -49
- package/dist/format.js.map +1 -1
- package/dist/server.js +71 -42
- package/dist/server.js.map +1 -1
- package/package.json +9 -4
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,61 @@ a customer reading it should not miss what appeared in the product. Like *Server
|
|
|
16
16
|
they are live from the day the web app was deployed, not from the package release they are
|
|
17
17
|
listed under.
|
|
18
18
|
|
|
19
|
+
## [0.21.0] - 2026-09-27
|
|
20
|
+
|
|
21
|
+
Faceless videos: an agent can now make a video of up to 90 seconds without an on-camera presenter, from a script or
|
|
22
|
+
from a short brief, and see the price before anything is made.
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- `quote_faceless` and `make_faceless` MCP tools, `quoteFaceless` and `startFaceless` in the SDK, and the
|
|
27
|
+
`quote-faceless` and `make-faceless` CLI commands. The video is narration over an opening animated clip and image
|
|
28
|
+
scenes, with captions on by default. `duration_seconds` (30 to 90) is a target: the video ends with its narration
|
|
29
|
+
and runs from 25 seconds to 5 seconds past `duration_seconds`, never past 90. `quote_faceless` is free;
|
|
30
|
+
`make_faceless` returns a `run_id`, and `get_run` reports progress. The MCP server now lists fourteen tools.
|
|
31
|
+
|
|
32
|
+
### Server-side
|
|
33
|
+
|
|
34
|
+
- A faceless run is charged for the video it delivers, by its actual length, and never more than its quote: seconds
|
|
35
|
+
past `duration_seconds` are free. A failed
|
|
36
|
+
run is charged nothing, including one we stop ourselves because a step did not meet our checks. A run held for
|
|
37
|
+
review keeps its credit hold until it is resolved.
|
|
38
|
+
- Captions drop surrounding punctuation, keep accents and other diacritics, and show numbers as written (`$3.50`,
|
|
39
|
+
`10:30`, `1,000`, `50%`, `-20`).
|
|
40
|
+
- With captions on, the script is checked against the caption font before speech is generated; a character the font
|
|
41
|
+
cannot draw fails the run without a customer charge.
|
|
42
|
+
- Narration uses automatic language detection.
|
|
43
|
+
- Pictures change about every three seconds, between spoken words.
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- *Server-side* Voice catalog: `cs_female_jana` is now listed with use case `advertisement` (was `narrative_story`);
|
|
48
|
+
the notice period is 4015 days for `en_female_cassidy` (was 730) and 730 days for `fi_male_jaakko` (was 365).
|
|
49
|
+
`es_male_benjamin` is unchanged and remains available.
|
|
50
|
+
|
|
51
|
+
### Known limits
|
|
52
|
+
|
|
53
|
+
- The voice reads some abbreviations literally: write "1.5 million" rather than "1.5M".
|
|
54
|
+
- A generated picture can come out as a collage of two or three panels, and small character details (glasses,
|
|
55
|
+
for instance) can change between pictures.
|
|
56
|
+
- Narration is not loudness-normalized yet, so a video can play quieter than other clips in the same feed.
|
|
57
|
+
- *Server-side* A faceless run can fail when the opening clip shows a pattern our text check mistakes for lettering
|
|
58
|
+
(a chain, for instance). The run is charged nothing; running it again produces a new video.
|
|
59
|
+
|
|
60
|
+
## [0.20.0] - 2026-09-25
|
|
61
|
+
|
|
62
|
+
The MCP server is ready for directories: it has a name in the official MCP
|
|
63
|
+
Registry, and every tool tells the host whether it only reads or writes.
|
|
64
|
+
|
|
65
|
+
### Added
|
|
66
|
+
|
|
67
|
+
- Every MCP tool now carries a `title` and the `readOnlyHint`/`destructiveHint`
|
|
68
|
+
annotations: quotes, lists and reads are read-only, `delete_actor` is
|
|
69
|
+
destructive, and `make_ugc`, `create_actor`, `upload_image` and
|
|
70
|
+
`set_actor_defaults` write.
|
|
71
|
+
- `@clipwright/mcp-server` declares `mcpName: io.clipwright/mcp` for the official
|
|
72
|
+
MCP Registry.
|
|
73
|
+
|
|
19
74
|
## [0.19.0] - 2026-09-22
|
|
20
75
|
|
|
21
76
|
A paid video that arrived after we stopped waiting can now be collected: the run
|
package/README.md
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
# @clipwright/mcp-server
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Your coding agent writes the script; [Clipwright](https://clipwright.io) renders
|
|
4
|
+
a short vertical video of an actor speaking it, 1080×1920 by default. The agent
|
|
5
|
+
asks for a free quote before it spends anything, and whatever the API cannot
|
|
6
|
+
honor comes back in `warnings[]` instead of being dropped silently.
|
|
7
|
+
|
|
8
|
+
The agent gets a `run_id` at once and polls until the video URL is ready.
|
|
9
|
+
Clipwright returns the file; it does not publish anywhere. Quotes, voices,
|
|
10
|
+
actors and the account balance are free. Renders spend credits: an account opened
|
|
11
|
+
by signing up starts with none, so buy a pack at [clipwright.io/pricing](https://clipwright.io/pricing)
|
|
12
|
+
before the first one.
|
|
6
13
|
|
|
7
14
|
## Install
|
|
8
15
|
|
|
@@ -28,7 +35,7 @@ Any MCP host works — the server speaks JSON-RPC over stdio.
|
|
|
28
35
|
|
|
29
36
|
- `list_voices` — voices for `voice`: the presets and the catalog, with
|
|
30
37
|
filters by language, gender, age, use case and model, and a short audio
|
|
31
|
-
sample
|
|
38
|
+
sample where the voice has one. Free, spends no credits.
|
|
32
39
|
- `list_actors` — ready-made faces with stable ids and verified formats. Free.
|
|
33
40
|
- `quote_ugc` — estimated duration and price, plus a warning when `make_ugc`
|
|
34
41
|
with the same input would be refused for money or access. Free.
|
|
@@ -43,8 +50,15 @@ Any MCP host works — the server speaks JSON-RPC over stdio.
|
|
|
43
50
|
money.** Each requested format is a separate charged image. Returns a `run_id`
|
|
44
51
|
immediately; poll `get_run` until `succeeded`, then pass `created_actor.actor_id`
|
|
45
52
|
to `make_ugc` as `actor_id`.
|
|
53
|
+
- `quote_faceless` — price of a faceless video before making one. Free.
|
|
54
|
+
- `make_faceless` — **makes a 30–90 second faceless video from your script or
|
|
55
|
+
from a short brief; this costs money.** Narration plays over an opening
|
|
56
|
+
animated clip and image scenes, with captions on by default. Returns a
|
|
57
|
+
`run_id` immediately; poll `get_run` until `succeeded`.
|
|
46
58
|
- `delete_actor` — removes a personal actor of this account. Videos already made
|
|
47
59
|
with it stay as they are. Free.
|
|
60
|
+
- `get_actor_defaults`, `set_actor_defaults` — read and save an actor's B-roll
|
|
61
|
+
default. It is stored only: today's talking-actor videos do not use it. Free.
|
|
48
62
|
|
|
49
63
|
Call `quote_ugc` before `make_ugc`: the quote is where the contract tells you
|
|
50
64
|
what it will and will not honor. Anything the API cannot deliver comes back in
|
|
@@ -56,3 +70,10 @@ a failed run on purpose, not a free refresh.
|
|
|
56
70
|
|
|
57
71
|
`SKILL.md` ships inside the package with the full operating instructions, and
|
|
58
72
|
`CHANGELOG.md` next to it says what changed in each release and what was removed.
|
|
73
|
+
|
|
74
|
+
## Privacy
|
|
75
|
+
|
|
76
|
+
The server sends your script, chosen options and any uploaded image to the
|
|
77
|
+
Clipwright API to quote and render the video. How that data is handled:
|
|
78
|
+
[clipwright.io/privacy](https://clipwright.io/privacy). Documentation:
|
|
79
|
+
[clipwright.io/docs](https://clipwright.io/docs).
|
package/SKILL.md
CHANGED
|
@@ -164,8 +164,9 @@ Environment variables:
|
|
|
164
164
|
| `CLIPWRIGHT_CLIENT_ID` | YES (see section 2) | Unique identifier of this INSTALLATION. |
|
|
165
165
|
|
|
166
166
|
After connecting, restart or reopen the MCP host and confirm that `tools/list`
|
|
167
|
-
returns
|
|
168
|
-
`create_actor`, `quote_actor`, `delete_actor
|
|
167
|
+
returns fourteen tools: `make_ugc`, `get_run`, `quote_ugc`, `list_actors`, `list_voices`, `upload_image`, `get_account`,
|
|
168
|
+
`create_actor`, `quote_actor`, `delete_actor`, `get_actor_defaults`, `set_actor_defaults`, `quote_faceless`,
|
|
169
|
+
`make_faceless`.
|
|
169
170
|
|
|
170
171
|
## 2. `CLIPWRIGHT_CLIENT_ID` — required, and WHY
|
|
171
172
|
|
|
@@ -305,7 +306,7 @@ frame could only come from the vendor's centre crop, which we do not do silently
|
|
|
305
306
|
To get `1:1`, select an actor with a verified square variant or pass an `image`
|
|
306
307
|
with a square public https source. An unavailable actor format is refused before payment.
|
|
307
308
|
|
|
308
|
-
## 4. The
|
|
309
|
+
## 4. The tools
|
|
309
310
|
|
|
310
311
|
Schemas come from the single source of truth `@clipwright/core`
|
|
311
312
|
(`packages/core/src/skills.ts`, barrel `packages/core/src/index.ts`); MCP does not
|
|
@@ -561,6 +562,41 @@ would be refused for money or access, so a render rarely needs this call first.
|
|
|
561
562
|
Call it when the user asks how many credits are left, or to show the numbers
|
|
562
563
|
behind such a warning.
|
|
563
564
|
|
|
565
|
+
### `quote_faceless` — free, and `make_faceless` — paid, creates a run
|
|
566
|
+
|
|
567
|
+
A faceless video is 30 to 90 seconds of narration over an opening animated clip
|
|
568
|
+
and image scenes, with no actor on screen. Captions are on by default; pass
|
|
569
|
+
`captions: false` to turn them off.
|
|
570
|
+
|
|
571
|
+
Give the narration one of two ways, and name which with `input_mode`:
|
|
572
|
+
|
|
573
|
+
- `input_mode: "script"` with `script` — your exact text is read as written.
|
|
574
|
+
The video ends with the narration, runs at least 25 seconds and may exceed
|
|
575
|
+
`duration_seconds` by up to 5 seconds, never beyond 90 seconds. A script must
|
|
576
|
+
fit this output range. The charge follows the delivered duration and never
|
|
577
|
+
exceeds the quote; the minimum is 200 base credits plus 150 for the opener.
|
|
578
|
+
- `input_mode: "brief"` with `brief` — a short description; the narration is
|
|
579
|
+
written from it.
|
|
580
|
+
|
|
581
|
+
Send exactly one of `script` and `brief`, the one that matches `input_mode`. The
|
|
582
|
+
tool schema lists both as optional because MCP cannot express "one or the
|
|
583
|
+
other"; the server and this client both refuse a mismatch, and the client
|
|
584
|
+
refuses it before any request is sent.
|
|
585
|
+
|
|
586
|
+
`duration_seconds` (30 to 90, on a 1/25 s frame boundary) is required. Optional:
|
|
587
|
+
`style_reference` (a public https image the scenes follow in style),
|
|
588
|
+
`character_reference` (a public https image of a person or figure to keep
|
|
589
|
+
consistent) and `scene_images` (your own images, each anchored to a word range
|
|
590
|
+
or a quote of the narration). An uploaded image must belong to this account.
|
|
591
|
+
|
|
592
|
+
Call `quote_faceless` first and show the user the price: it spends nothing and
|
|
593
|
+
warns when `make_faceless` would be refused for money or access. `make_faceless`
|
|
594
|
+
returns a `run_id` at once; poll `get_run` until `succeeded` (with `video_url`)
|
|
595
|
+
or `failed`. As with `make_ugc`, a repeated call with the same input returns the
|
|
596
|
+
same run, and `attempt` 2, 3, … deliberately starts a new paid one. When
|
|
597
|
+
faceless generation is switched off on the server, both tools answer
|
|
598
|
+
`paid_render_disabled` and nothing is charged.
|
|
599
|
+
|
|
564
600
|
## 5. Retrying a failed run is NOT a permanent refusal
|
|
565
601
|
|
|
566
602
|
If `get_run` returned a terminal `FAILED` and you call `make_ugc` AGAIN with the
|
package/dist/format.js
CHANGED
|
@@ -1,24 +1,7 @@
|
|
|
1
1
|
import { FAILED_STATE, isTerminal, runMoney, VIDEO_URL_CHECK } from "@clipwright/core";
|
|
2
2
|
import { ClipwrightApiError } from "@clipwright/sdk";
|
|
3
|
-
/**
|
|
4
|
-
|
|
5
|
-
*
|
|
6
|
-
* ЗАЧЕМ ОБЁРТКА, ЕСЛИ ИСКЛЮЧЕНИЕ И ТАК ДОЕЗЖАЕТ. Доезжает — одной строкой:
|
|
7
|
-
* MCP SDK превращает брошенную ошибку в `isError` с текстом сообщения. Для
|
|
8
|
-
* «поле не то» этого хватало, для денег — нет. 402 значит «остановись и скажи
|
|
9
|
-
* человеку числа», 429 значит «подожди столько-то и повтори ТОТ ЖЕ вызов», и
|
|
10
|
-
* различить их в свободном тексте агент может только угадыванием. Здесь он
|
|
11
|
-
* получает `retryable`, `next_action` и сами числа полями.
|
|
12
|
-
*
|
|
13
|
-
* ПОЧЕМУ ТОЛЬКО `ClipwrightApiError`, А НЕ ЛЮБАЯ ОШИБКА. Остальные — местные:
|
|
14
|
-
* нерезолвящийся `CLIPWRIGHT_CLIENT_ID`, сеть, битый baseUrl. У них нет ни
|
|
15
|
-
* статуса, ни кода отказа, и завернуть их в ту же форму значило бы приписать им
|
|
16
|
-
* ответ сервера, которого не было. Они летят дальше как есть, и MCP SDK отдаёт
|
|
17
|
-
* их текст — там он и уместен.
|
|
18
|
-
*
|
|
19
|
-
* `isError: true` остаётся: отказ есть отказ. Меняется не факт, а то, СКОЛЬКО
|
|
20
|
-
* агент о нём узнаёт.
|
|
21
|
-
*/
|
|
3
|
+
/** An API refusal expanded for the agent: `retryable`, `next_action` and numbers */
|
|
4
|
+
/** as fields. Local errors rethrow, since they carry no server answer. */
|
|
22
5
|
export function formatFailure(error) {
|
|
23
6
|
if (!(error instanceof ClipwrightApiError))
|
|
24
7
|
throw error;
|
|
@@ -27,14 +10,8 @@ export function formatFailure(error) {
|
|
|
27
10
|
isError: true,
|
|
28
11
|
};
|
|
29
12
|
}
|
|
30
|
-
/**
|
|
31
|
-
|
|
32
|
-
*
|
|
33
|
-
* Обёртка одна на все четыре тула намеренно: забытый `try` в одном из них дал
|
|
34
|
-
* бы агенту плоский текст ровно там, где отказ денежный, — и обнаружилось бы
|
|
35
|
-
* это у клиента. Через общую обёртку забыть нельзя: она либо стоит, либо тул не
|
|
36
|
-
* собирается.
|
|
37
|
-
*/
|
|
13
|
+
/** Tool body with API refusals expanded for the agent; shared by every tool so */
|
|
14
|
+
/** no tool can forget the `try`. */
|
|
38
15
|
export async function withFailureReport(body) {
|
|
39
16
|
try {
|
|
40
17
|
return await body();
|
|
@@ -43,26 +20,12 @@ export async function withFailureReport(body) {
|
|
|
43
20
|
return formatFailure(error);
|
|
44
21
|
}
|
|
45
22
|
}
|
|
46
|
-
/**
|
|
47
|
-
|
|
48
|
-
* тестировать терминальную форму без подъёма stdio-транспорта и env).
|
|
49
|
-
*
|
|
50
|
-
* ОБЕ терминальные ветки несут И `status` (SUCCEEDED/FAILED — императив для
|
|
51
|
-
* агента), И `state` (фактический `run.state` — исправление US-501, контракт
|
|
52
|
-
* поллинга: терминал теперь виден в самом `state`, не только в `status`).
|
|
53
|
-
*
|
|
54
|
-
* Осознанная деградация (минор Critic №3, зафиксировать в docs/15): неизвестный
|
|
55
|
-
* ТЕРМИНАЛЬНЫЙ статус сервера (напр. `"canceled"`) НЕ входит в `TERMINAL_STATES`
|
|
56
|
-
* → `isTerminal=false` → проваливается в IN_PROGRESS-ветку (агенту скажут
|
|
57
|
-
* «продолжай поллить» про завершённый ран). В прототипе это принято осознанно:
|
|
58
|
-
* MCP и API деплоятся одной версией, а против текущего краша это строгое
|
|
59
|
-
* улучшение.
|
|
60
|
-
*/
|
|
23
|
+
/** Pure `get_run` formatter. Terminal answers carry both `status` and `state`; */
|
|
24
|
+
/** an unknown terminal state falls into IN_PROGRESS by design. */
|
|
61
25
|
export function formatGetRun(run) {
|
|
62
26
|
if (isTerminal(run.state)) {
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
// успех/провал).
|
|
27
|
+
// Outcome by core's named constant, not an array index that reordering
|
|
28
|
+
// could silently invert.
|
|
66
29
|
if (run.state === FAILED_STATE) {
|
|
67
30
|
return {
|
|
68
31
|
content: [
|
|
@@ -73,8 +36,7 @@ export function formatGetRun(run) {
|
|
|
73
36
|
run_id: run.run_id,
|
|
74
37
|
state: run.state,
|
|
75
38
|
...runMoney(run),
|
|
76
|
-
//
|
|
77
|
-
// пробрасываются в КАЖДУЮ ветку get_run (US-512).
|
|
39
|
+
// Warnings are never silent: every get_run branch carries them.
|
|
78
40
|
warnings: run.warnings,
|
|
79
41
|
error: run.error,
|
|
80
42
|
}),
|
|
@@ -102,8 +64,7 @@ export function formatGetRun(run) {
|
|
|
102
64
|
],
|
|
103
65
|
};
|
|
104
66
|
}
|
|
105
|
-
//
|
|
106
|
-
// тот же императивный формат, что и у make_ugc.
|
|
67
|
+
// Non-terminal (or unknown terminal) state: the same imperative format as make_ugc.
|
|
107
68
|
return {
|
|
108
69
|
content: [
|
|
109
70
|
{
|
package/dist/format.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAgB,MAAM,kBAAkB,CAAC;AACrG,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -2,70 +2,60 @@ import { readFile } from "node:fs/promises";
|
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
4
|
import { z } from "zod";
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
// `rejected` не должны предлагаться вызывателю, которого мы за их использование
|
|
9
|
-
// накажем четырёхсотым (блокер B4). Множество выводится из реестра диспозиций,
|
|
10
|
-
// поэтому смена решения по полю переносит его между поверхностями одной строкой.
|
|
11
|
-
import { offeredUgcInputShape, actorDefaultsInput, BROLL_POLICY_DESCRIPTION, CATALOG_LANGUAGES, CREATE_ACTOR_DESCRIPTION, createActorInputShape, SCRIPT_LENGTH_DESCRIPTION, voicesQueryShape, agentRetryShape, runId, MAKE_UGC_DESCRIPTION, MAKE_UGC_AGENT_PROTOCOL, UPLOAD_IMAGE_DESCRIPTION, UPLOAD_MAX_BYTES, sniffUploadMediaType, } from "@clipwright/core";
|
|
5
|
+
// `offeredUgcInputShape`, not the full shape: fields the server rejects must not
|
|
6
|
+
// be offered to a caller who would get a 400 for using them.
|
|
7
|
+
import { offeredUgcInputShape, actorDefaultsInput, BROLL_POLICY_DESCRIPTION, CATALOG_LANGUAGES, CREATE_ACTOR_DESCRIPTION, createActorInputShape, SCRIPT_LENGTH_DESCRIPTION, voicesQueryShape, agentRetryShape, runId, MAKE_UGC_DESCRIPTION, MAKE_UGC_AGENT_PROTOCOL, MAKE_FACELESS_DESCRIPTION, MAKE_FACELESS_AGENT_PROTOCOL, makeFacelessInput, offeredFacelessInputShape, UPLOAD_IMAGE_DESCRIPTION, UPLOAD_MAX_BYTES, sniffUploadMediaType, } from "@clipwright/core";
|
|
12
8
|
import { formatGetRun, withFailureReport } from "./format.js";
|
|
13
|
-
//
|
|
9
|
+
// Version from the manifest: a literal drifts, and a JSON import breaks `rootDir`.
|
|
14
10
|
const packageVersion = () => createRequire(import.meta.url)("../package.json").version;
|
|
15
|
-
/**
|
|
16
|
-
|
|
17
|
-
*
|
|
18
|
-
* Вынесено из index.ts (US-516): index.ts раньше и строил сервер, И сразу
|
|
19
|
-
* коннектил его к stdio на верхнем уровне модуля — это делало регистрацию
|
|
20
|
-
* тулов непроверяемой без реального stdio-процесса. Разделение — тот же
|
|
21
|
-
* паттерн, что app.ts/index.ts в apps/api (app — тестируемый, index —
|
|
22
|
-
* тонкий bootstrap).
|
|
23
|
-
*/
|
|
11
|
+
/** Builds the MCP server with its tools registered but NO transport connected, */
|
|
12
|
+
/** so tool registration is testable without a stdio process. */
|
|
24
13
|
export function createServer(client) {
|
|
25
14
|
const server = new McpServer({ name: "clipwright", version: packageVersion() });
|
|
26
|
-
//
|
|
15
|
+
// tools/list publishes the full schema; an empty schema leaves agents guessing.
|
|
27
16
|
server.registerTool("make_ugc", {
|
|
17
|
+
title: "Make a talking-actor video",
|
|
18
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
28
19
|
description: `${MAKE_UGC_DESCRIPTION} ${MAKE_UGC_AGENT_PROTOCOL}`,
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
// намеренно: LLM-вызыватель читает описание РАНЬШЕ схемы, поэтому обещание
|
|
32
|
-
// в тексте («1080p 9:16», «character») было бы тем же дефектом
|
|
33
|
-
// «предлагаем и наказываем», просто слоем выше.
|
|
20
|
+
// Flat schema: offered render input plus agent retry. The description must agree
|
|
21
|
+
// with it, since an LLM reads the description before the schema.
|
|
34
22
|
inputSchema: { ...offeredUgcInputShape, ...agentRetryShape },
|
|
35
23
|
}, async (args) => withFailureReport(async () => {
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
// лишний ключ → суффикс всегда `:1` → повтор вернёт тот же run → M1 мёртв.
|
|
24
|
+
// `attempt` goes in SDK opts: inside `input` the schema would strip it,
|
|
25
|
+
// and a retry would return the same run.
|
|
39
26
|
const { attempt, ...input } = args;
|
|
40
|
-
//
|
|
27
|
+
// Return right after start (state≈"queued"), without waiting.
|
|
41
28
|
const run = await client.startUgc(input, { attempt });
|
|
42
|
-
//
|
|
43
|
-
// `run.warnings`, и агент узнавал о снапе уже после платного старта.
|
|
29
|
+
// Same formatter as `get_run`, so warnings reach the agent at once.
|
|
44
30
|
return formatGetRun(run);
|
|
45
31
|
}));
|
|
46
32
|
server.registerTool("get_run", {
|
|
47
|
-
|
|
33
|
+
title: "Get run status",
|
|
34
|
+
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
35
|
+
description: "Check the status of a video generation started by make_ugc or make_faceless. Pass the run_id. While the run " +
|
|
48
36
|
"is still working it returns status IN_PROGRESS with a next_action telling you to poll again; " +
|
|
49
37
|
"repeat every ~5 seconds until it reaches a terminal state — SUCCEEDED (with video_url) or FAILED.",
|
|
50
38
|
inputSchema: { run_id: runId },
|
|
51
39
|
}, async ({ run_id }) => withFailureReport(async () => {
|
|
52
|
-
//
|
|
53
|
-
// без stdio-транспорта). Терминал несёт И `status`, И `state` (US-501).
|
|
40
|
+
// Terminal shape lives in the pure `formatGetRun`: both `status` and `state`.
|
|
54
41
|
const run = await client.getRun(run_id);
|
|
55
42
|
return formatGetRun(run);
|
|
56
43
|
}));
|
|
57
44
|
server.registerTool("quote_ugc", {
|
|
45
|
+
title: "Quote a video",
|
|
46
|
+
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
58
47
|
description: "Estimate the credit cost of a make_ugc call WITHOUT spending credits. " +
|
|
59
48
|
"Always call this first and show the user the price before make_ugc.",
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
-
// shape целиком вместо рукописного {script} — цена учитывает captions/look и не расходится со схемой.
|
|
49
|
+
// Same core shape as make_ugc, so the quote prices exactly what make_ugc
|
|
50
|
+
// would render.
|
|
63
51
|
inputSchema: offeredUgcInputShape,
|
|
64
52
|
}, async (args) => withFailureReport(async () => {
|
|
65
53
|
const quote = await client.quoteUgc(args);
|
|
66
54
|
return { content: [{ type: "text", text: JSON.stringify(quote) }] };
|
|
67
55
|
}));
|
|
68
56
|
server.registerTool("upload_image", {
|
|
57
|
+
title: "Upload an image",
|
|
58
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
69
59
|
description: UPLOAD_IMAGE_DESCRIPTION,
|
|
70
60
|
inputSchema: {
|
|
71
61
|
path: z.string().min(1).describe("Absolute or cwd-relative path to a PNG or JPEG file"),
|
|
@@ -95,6 +85,8 @@ export function createServer(client) {
|
|
|
95
85
|
};
|
|
96
86
|
}));
|
|
97
87
|
server.registerTool("list_voices", {
|
|
88
|
+
title: "List voices",
|
|
89
|
+
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
98
90
|
description: "List the voices for make_ugc's `voice` field: the presets first, then catalog voices in " +
|
|
99
91
|
`${CATALOG_LANGUAGES.length} languages. Filter by \`language\` (the voice's native language; any voice ` +
|
|
100
92
|
"speaks any supported language), `gender`, `age`, `use_case` and `model`; an unknown filter value is " +
|
|
@@ -109,45 +101,80 @@ export function createServer(client) {
|
|
|
109
101
|
"never store it. A voice without `preview_url` has no sample yet. Free. " + SCRIPT_LENGTH_DESCRIPTION,
|
|
110
102
|
inputSchema: voicesQueryShape,
|
|
111
103
|
}, async (filters) => withFailureReport(async () => {
|
|
112
|
-
//
|
|
104
|
+
// Relays /v1/voices: no vendor call and no vendor key on this surface.
|
|
113
105
|
const voices = await client.listVoices(filters);
|
|
114
106
|
return { content: [{ type: "text", text: JSON.stringify({ voices }) }] };
|
|
115
107
|
}));
|
|
116
108
|
server.registerTool("list_actors", {
|
|
109
|
+
title: "List actors",
|
|
110
|
+
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
117
111
|
description: "List saved Clipwright actors with stable IDs, gender, age and verified image formats. Choose actor_id for quote_ugc and make_ugc. Preview URLs expire; actor IDs remain reusable. Do not combine actor_id with image, person or actor_gender. Without voice, the actor speaks the default voice of their gender.",
|
|
118
112
|
inputSchema: {},
|
|
119
113
|
}, async () => withFailureReport(async () => ({
|
|
120
114
|
content: [{ type: "text", text: JSON.stringify({ actors: await client.listActors() }) }],
|
|
121
115
|
})));
|
|
122
116
|
server.registerTool("get_actor_defaults", {
|
|
117
|
+
title: "Get actor B-roll default",
|
|
118
|
+
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
123
119
|
description: `Read this account actor's saved B-roll default. ${BROLL_POLICY_DESCRIPTION}`,
|
|
124
120
|
inputSchema: { actor_id: z.string().min(1) },
|
|
125
121
|
}, async ({ actor_id }) => withFailureReport(async () => ({
|
|
126
122
|
content: [{ type: "text", text: JSON.stringify(await client.getActorDefaults(actor_id)) }],
|
|
127
123
|
})));
|
|
128
124
|
server.registerTool("set_actor_defaults", {
|
|
125
|
+
title: "Set actor B-roll default",
|
|
126
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },
|
|
129
127
|
description: `Save this account actor's B-roll default without spending credits. ${BROLL_POLICY_DESCRIPTION}`,
|
|
130
128
|
inputSchema: { actor_id: z.string().min(1), ...actorDefaultsInput.shape },
|
|
131
129
|
}, async ({ actor_id, ...input }) => withFailureReport(async () => ({
|
|
132
130
|
content: [{ type: "text", text: JSON.stringify(await client.setActorDefaults(actor_id, input)) }],
|
|
133
131
|
})));
|
|
134
|
-
//
|
|
135
|
-
//
|
|
136
|
-
server.registerTool("create_actor", {
|
|
137
|
-
|
|
138
|
-
|
|
132
|
+
// Personal actor: the same schema the server checks, so offered and accepted
|
|
133
|
+
// input cannot drift.
|
|
134
|
+
server.registerTool("create_actor", {
|
|
135
|
+
title: "Create a personal actor",
|
|
136
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
137
|
+
description: CREATE_ACTOR_DESCRIPTION,
|
|
138
|
+
inputSchema: { ...createActorInputShape, ...agentRetryShape },
|
|
139
|
+
}, async (args) => withFailureReport(async () => {
|
|
140
|
+
// `attempt` goes in SDK opts: inside `input` the schema would strip it,
|
|
141
|
+
// and a retry would return the first run.
|
|
139
142
|
const { attempt, ...input } = args;
|
|
140
143
|
const run = await client.createActor(input, { attempt });
|
|
141
144
|
return formatGetRun(run);
|
|
142
145
|
}));
|
|
143
146
|
server.registerTool("quote_actor", {
|
|
147
|
+
title: "Quote a personal actor",
|
|
148
|
+
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
144
149
|
description: "Estimate the credit cost of create_actor WITHOUT spending credits. Call this first and show the " +
|
|
145
150
|
"price before create_actor: each requested format is a separate charged image.",
|
|
146
151
|
inputSchema: createActorInputShape,
|
|
147
152
|
}, async (args) => withFailureReport(async () => ({
|
|
148
153
|
content: [{ type: "text", text: JSON.stringify(await client.quoteActor(args)) }],
|
|
149
154
|
})));
|
|
155
|
+
// Flat shape for tools/list; the union parse refuses a script/brief mismatch before the SDK call.
|
|
156
|
+
server.registerTool("make_faceless", {
|
|
157
|
+
title: "Make a faceless video",
|
|
158
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
159
|
+
description: `${MAKE_FACELESS_DESCRIPTION} ${MAKE_FACELESS_AGENT_PROTOCOL}`,
|
|
160
|
+
inputSchema: { ...offeredFacelessInputShape, ...agentRetryShape },
|
|
161
|
+
}, async (args) => withFailureReport(async () => {
|
|
162
|
+
const { attempt, ...input } = args;
|
|
163
|
+
const run = await client.startFaceless(makeFacelessInput.parse(input), { attempt });
|
|
164
|
+
return formatGetRun(run);
|
|
165
|
+
}));
|
|
166
|
+
server.registerTool("quote_faceless", {
|
|
167
|
+
title: "Quote a faceless video",
|
|
168
|
+
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
169
|
+
description: "Estimate the credit cost of make_faceless WITHOUT spending credits. " +
|
|
170
|
+
"Always call this first and show the user the price before make_faceless.",
|
|
171
|
+
inputSchema: offeredFacelessInputShape,
|
|
172
|
+
}, async (args) => withFailureReport(async () => ({
|
|
173
|
+
content: [{ type: "text", text: JSON.stringify(await client.quoteFaceless(makeFacelessInput.parse(args))) }],
|
|
174
|
+
})));
|
|
150
175
|
server.registerTool("delete_actor", {
|
|
176
|
+
title: "Delete a personal actor",
|
|
177
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
151
178
|
description: "Delete a personal actor of this account by actor_id. Videos already made with it stay as they are, " +
|
|
152
179
|
"and new runs can no longer use it. An actor used by a run that has not finished is refused until that " +
|
|
153
180
|
"run ends. Catalog actors belong to Clipwright and are not deletable.",
|
|
@@ -156,8 +183,10 @@ export function createServer(client) {
|
|
|
156
183
|
await client.deleteActor(actor_id);
|
|
157
184
|
return { content: [{ type: "text", text: JSON.stringify({ deleted: actor_id }) }] };
|
|
158
185
|
}));
|
|
159
|
-
//
|
|
186
|
+
// Balance without spending an attempt; otherwise only a 402 would reveal it.
|
|
160
187
|
server.registerTool("get_account", {
|
|
188
|
+
title: "Get account credits",
|
|
189
|
+
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
161
190
|
description: "Read this account's credits. Free, spends nothing. debt_credits above zero means make_ugc " +
|
|
162
191
|
"is refused with debt_outstanding whatever the balance, until the account buys credits; " +
|
|
163
192
|
"with no debt, balance_credits is what a new run can spend. holds_credits are reserved for " +
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clipwright/mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "MCP server for Clipwright: generate UGC videos from your coding agent",
|
|
5
|
+
"mcpName": "io.clipwright/mcp",
|
|
5
6
|
"keywords": [
|
|
6
7
|
"mcp",
|
|
8
|
+
"mcp-server",
|
|
7
9
|
"modelcontextprotocol",
|
|
8
10
|
"ugc",
|
|
9
|
-
"video"
|
|
11
|
+
"video",
|
|
12
|
+
"video-generation",
|
|
13
|
+
"ai-avatar",
|
|
14
|
+
"talking-head"
|
|
10
15
|
],
|
|
11
16
|
"license": "MIT",
|
|
12
17
|
"author": "Dimantika Sp. z o.o.",
|
|
@@ -29,8 +34,8 @@
|
|
|
29
34
|
"dependencies": {
|
|
30
35
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
31
36
|
"zod": "^4.4.3",
|
|
32
|
-
"@clipwright/core": "0.
|
|
33
|
-
"@clipwright/sdk": "0.
|
|
37
|
+
"@clipwright/core": "0.21.0",
|
|
38
|
+
"@clipwright/sdk": "0.21.0"
|
|
34
39
|
},
|
|
35
40
|
"devDependencies": {
|
|
36
41
|
"@types/node": "^26.1.1"
|