@craftstory/mcp 0.1.2 → 0.1.3

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 CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.3 - 2026-09-12
4
+ - tool annotations (readOnlyHint / destructiveHint) on every tool; Privacy Policy section in the README
5
+ - MCPB bundle for Claude Desktop (manifest.json, icon) attached to GitHub releases
6
+ - `mcpName` for the official MCP Registry; server.json
7
+
3
8
  ## 0.1.2 - 2026-09-12
4
9
  - package metadata: public repository and issue tracker on GitHub (itseez3d/craftstory-mcp); CHANGELOG shipped
5
10
  - wait_for_job: every request inside the wait is capped by the time left, so the call really returns within timeout_s (+ a few seconds for the result fetch)
package/README.md CHANGED
@@ -81,6 +81,15 @@ npm test
81
81
 
82
82
  Full API reference: https://api.craftstory.com/api/v1/docs/public/ and the curl walkthrough at https://api.craftstory.com/api/v1/docs/samples/curl/.
83
83
 
84
+ ## Privacy Policy
85
+
86
+ This server runs on your machine and keeps no data of its own. It sends your API key and the inputs you pass to tools
87
+ (text, photos, audio, reference files) only to the CraftStory API at `CRAFTSTORY_API_BASE` (default
88
+ `https://api.craftstory.com`), where they are processed under the CraftStory privacy policy:
89
+ https://craftstory.com/privacy/. Generated videos and uploaded files are stored in your CraftStory account and can be
90
+ deleted there or via the API; nothing is retained locally by the server. No analytics or third-party services are
91
+ called by the server itself. Questions: support via https://craftstory.com/contacts/.
92
+
84
93
  ## License
85
94
 
86
95
  MIT
package/dist/client.js CHANGED
@@ -6,7 +6,7 @@ import { readFile } from "node:fs/promises";
6
6
  import { homedir } from "node:os";
7
7
  import { basename } from "node:path";
8
8
  export const DEFAULT_BASE = "https://api.craftstory.com/api/v1";
9
- export const USER_AGENT = "craftstory-mcp/0.1.2";
9
+ export const USER_AGENT = "craftstory-mcp/0.1.3";
10
10
  /** Per-request HTTP timeout; keeps every tool call well under MCP clients' ~60 s limit. */
11
11
  export const REQUEST_TIMEOUT_MS = 25_000;
12
12
  export class ApiError extends Error {
package/dist/server.js CHANGED
@@ -14,9 +14,10 @@ const JOB_KINDS = ["craftstory-2", "minimax-h3", "audio-clip"];
14
14
  const text = (data) => ({ content: [{ type: "text", text: typeof data === "string" ? data : JSON.stringify(data, null, 2) }] });
15
15
  const fail = (err) => ({ isError: true, content: [{ type: "text", text: err instanceof Error ? err.message : String(err) }] });
16
16
  export function buildServer(client) {
17
- const server = new McpServer({ name: "craftstory", version: "0.1.2" });
17
+ const server = new McpServer({ name: "craftstory", version: "0.1.3" });
18
18
  server.registerTool("list_models", {
19
19
  title: "List CraftStory video models",
20
+ annotations: { readOnlyHint: true, openWorldHint: true },
20
21
  description: "Catalogue of the video models behind this server with their status, modes, limits and credit prices. " +
21
22
  "Two models today: craftstory-2 (a talking video of any length from one photo plus an audio clip; 8-15 min) " +
22
23
  "and minimax-h3 (a clip of up to 15 s from one photo, either description-driven with generated sound or audio-driven with lip-sync; 1-3 min). " +
@@ -32,6 +33,7 @@ export function buildServer(client) {
32
33
  });
33
34
  server.registerTool("list_voices", {
34
35
  title: "List voices for text-to-speech",
36
+ annotations: { readOnlyHint: true, openWorldHint: true },
35
37
  description: "Library voices (id, name, language, gender) usable as voice_id in create_audio_clip. " +
36
38
  "With include_cloned=true also returns the account's own cloned voices, usable as voice_user_id. Voices are cloned in the CraftStory app, not via the API.",
37
39
  inputSchema: { include_cloned: z.boolean().optional().describe("Also return the account's cloned voices (default false)") },
@@ -47,6 +49,7 @@ export function buildServer(client) {
47
49
  });
48
50
  server.registerTool("list_avatars", {
49
51
  title: "List custom avatars (and their scenes)",
52
+ annotations: { readOnlyHint: true, openWorldHint: true },
50
53
  description: "Custom avatars trained in the CraftStory app that craftstory-2 can generate with (pass an id as avatar_id). " +
51
54
  "Each avatar may carry a default voice {id, voice_kind}: voice_kind 'user' means send it as voice_user_id, 'library' as voice_id in create_audio_clip. " +
52
55
  "Pass avatar_id to list that avatar's scenes; a scene id can replace the photo (scene_id) in create_craftstory2_video.",
@@ -61,6 +64,7 @@ export function buildServer(client) {
61
64
  });
62
65
  server.registerTool("create_audio_clip", {
63
66
  title: "Create an audio clip (speech from text, or upload a recording)",
67
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
64
68
  description: "The soundtrack every video model takes as input. Either text (up to 2000 characters) plus exactly one voice (voice_id from list_voices, or voice_user_id for a cloned voice), " +
65
69
  "or file_path to upload a local WAV/MP3/M4A recording. Returns the clip id; it is ready when wait_for_job(model='audio-clip') reports done (usually seconds). " +
66
70
  "Longer scripts: create several clips and pass all ids to create_craftstory2_video in order.",
@@ -90,6 +94,7 @@ export function buildServer(client) {
90
94
  });
91
95
  server.registerTool("preview_cost", {
92
96
  title: "Estimate the credit cost of a CraftStory 2.0 video",
97
+ annotations: { readOnlyHint: true, openWorldHint: true },
93
98
  description: "Credits a craftstory-2 job would cost for the given audio clips and settings, without creating anything. " +
94
99
  "Rate per second of audio: 480p 2.2 (2 with lipsync_mode=empty), 720p 3.3 (3 with empty); rounded up per job. MiniMax H3 is a flat 3.3 credits per billed second.",
95
100
  inputSchema: {
@@ -107,6 +112,7 @@ export function buildServer(client) {
107
112
  });
108
113
  server.registerTool("create_craftstory2_video", {
109
114
  title: "Create a CraftStory 2.0 talking video (photo + audio)",
115
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
110
116
  description: "Start a craftstory-2 generation: a photo of a person (image_url or image_path, or a custom avatar scene via scene_id) speaks the given audio clips with lip-sync, gestures and natural motion; any length. " +
111
117
  "resolution is WIDTH_HEIGHT (480_832 / 720_1280 portrait, 832_480 / 1280_720 landscape); 1080p is available afterwards via upscale_video. " +
112
118
  "Credits are charged on create (see preview_cost) and refunded if the job fails. Returns the job id and initial status; generation takes 8-15 minutes, " +
@@ -148,6 +154,7 @@ export function buildServer(client) {
148
154
  });
149
155
  server.registerTool("create_minimax_h3_video", {
150
156
  title: "Create a MiniMax H3 clip (up to 15 s)",
157
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
151
158
  description: "Start a minimax-h3 generation from one photo. mode='basic': user_prompt (scene description) + requested_duration_s (5-15); the model animates the photo and generates the soundtrack itself. " +
152
159
  "mode='reference': one audio_clip_id drives the clip with lip-sync (first 15 s billed); user_prompt is optional; up to 8 extra image / 3 video / 2 audio reference_files with reference_captions keep a product or background consistent. " +
153
160
  "Output is 768 px on the short side, orientation follows the photo. Cost 3.3 credits per billed second, charged on create. Returns the job id; call wait_for_job(model='minimax-h3') until done (1-3 min).",
@@ -188,6 +195,7 @@ export function buildServer(client) {
188
195
  });
189
196
  server.registerTool("get_job_status", {
190
197
  title: "Get a job's status",
198
+ annotations: { readOnlyHint: true, openWorldHint: true },
191
199
  description: "Status of a video job or audio clip: status, status_percentage, status_failed, credits_refunded. Terminal states: done; failed*, rejected_* and not_pass_moderation (audio) are failures. " +
192
200
  "Prefer wait_for_job, which polls for you.",
193
201
  inputSchema: { model: z.enum(JOB_KINDS), id: z.string().uuid() },
@@ -201,6 +209,7 @@ export function buildServer(client) {
201
209
  });
202
210
  server.registerTool("get_job_result", {
203
211
  title: "Get a finished job (video URL and details)",
212
+ annotations: { readOnlyHint: true, openWorldHint: true },
204
213
  description: "Full record of a job. For craftstory-2 the video is in `video`, for minimax-h3 in `video_url`, for audio clips in `file`; all are signed URLs valid for 7 days (call again for a fresh link). Also returns the parameters used and the credits charged.",
205
214
  inputSchema: { model: z.enum(JOB_KINDS), id: z.string().uuid() },
206
215
  }, async ({ model, id }) => {
@@ -213,6 +222,7 @@ export function buildServer(client) {
213
222
  });
214
223
  server.registerTool("wait_for_job", {
215
224
  title: "Wait for a job (bounded polling)",
225
+ annotations: { readOnlyHint: true, openWorldHint: true },
216
226
  description: "Polls a job's status every few seconds for up to timeout_s (default 45, max 55 - most MCP clients cut a tool call at 60 s) and returns as soon as it is terminal. " +
217
227
  "If it returns state='running', call it again - craftstory-2 jobs take 8-15 minutes, minimax-h3 1-3 minutes, audio clips seconds. Reports progress notifications when the client supports them.",
218
228
  inputSchema: {
@@ -264,6 +274,7 @@ export function buildServer(client) {
264
274
  });
265
275
  server.registerTool("upscale_video", {
266
276
  title: "Upscale a finished video (new job)",
277
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
267
278
  description: "Creates a NEW job with the upscaled result; the original stays. craftstory-2: only 720p sources, resolution 1080_1920 (from 720_1280) or 1920_1080 (from 1280_720). minimax-h3: always 2x, no resolution needed. " +
268
279
  "Costs 0.2 credits per second. Poll the returned id with wait_for_job.",
269
280
  inputSchema: {
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@craftstory/mcp",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
+ "mcpName": "io.github.itseez3d/craftstory-mcp",
4
5
  "description": "MCP server for the CraftStory API: talking-avatar videos from a photo (CraftStory 2.0) and short clips with generated sound (MiniMax H3), from Claude, Cursor and other MCP clients.",
5
6
  "type": "module",
6
7
  "bin": {