@instavar/mcp-server 0.2.1 → 0.3.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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +29 -12
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![CI](https://github.com/instavar/mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/instavar/mcp-server/actions/workflows/ci.yml)
4
4
  [![npm](https://img.shields.io/npm/v/%40instavar%2Fmcp-server)](https://www.npmjs.com/package/@instavar/mcp-server)
5
- [![MCP server on Glama](https://glama.ai/mcp/servers/instavar/mcp-server/badge)](https://glama.ai/mcp/servers/instavar/mcp-server)
5
+ [![Glama score](https://glama.ai/mcp/servers/instavar/mcp-server/badges/score.svg)](https://glama.ai/mcp/servers/instavar/mcp-server)
6
6
 
7
7
  Drive the full [Instavar Studio](https://instavar.com) video workflow —
8
8
  **create → render → approve → publish → metrics** — from Claude Code or Codex,
package/dist/index.js CHANGED
@@ -153,6 +153,7 @@ var briefSceneSchema = z.object({
153
153
  "custom"
154
154
  ]),
155
155
  durationInFrames: z.number().optional(),
156
+ narrationText: z.string().optional(),
156
157
  title: z.string().optional(),
157
158
  subtitle: z.string().optional(),
158
159
  text: z.string().optional(),
@@ -172,7 +173,13 @@ var briefSceneSchema = z.object({
172
173
  totalSteps: z.number().optional(),
173
174
  items: z.array(z.object({ label: z.string(), value: z.number() })).optional(),
174
175
  src: z.string().optional(),
175
- caption: z.string().optional()
176
+ caption: z.string().optional(),
177
+ // A-roll generation (video-window scenes): source "generate" triggers
178
+ // flag-gated WaveSpeed image/video gen server-side from generatePrompt;
179
+ // "url" (default) uses src as-is. Kept in sync with the app's
180
+ // briefSceneSchema - see the parity test in the app suite.
181
+ source: z.enum(["url", "generate"]).optional(),
182
+ generatePrompt: z.string().optional()
176
183
  });
177
184
  var directionsBriefSchema = z.object({
178
185
  subtitle: z.string().optional(),
@@ -221,8 +228,15 @@ var createBriefShape = {
221
228
  lessonTitle: z.string().optional().describe("Display title rendered inside the video"),
222
229
  steps: z.array(briefStepSchema).optional().describe("Structured steps for educational content (LaTeX)"),
223
230
  scenes: z.array(briefSceneSchema).optional().describe("Scene graph for the UniversalVideo composition"),
224
- aspectRatio: z.enum(ASPECT_RATIOS).default("9:16").describe("Aspect ratio (default 9:16)"),
231
+ // No zod .default() here: a default would materialize into the parsed tool
232
+ // arguments and relay to /api/v1/jobs as if the caller stated it, corrupting
233
+ // the resolution provenance the API echoes back. Unset must stay absent;
234
+ // the API re-applies 9:16 server-side.
235
+ aspectRatio: z.enum(ASPECT_RATIOS).optional().describe("Aspect ratio (defaults to 9:16 when omitted)"),
225
236
  compositionId: z.string().optional().describe("Remotion composition ID override (advanced)"),
237
+ voiceId: z.string().optional().describe(
238
+ "TTS narrator voice ID. Unknown IDs are rejected before rendering; when omitted, the org's saved voice preference or the system default is used and reported in the response's resolution block."
239
+ ),
226
240
  directions: directionsBriefSchema.optional().describe(
227
241
  "DirectionsWalkthrough 'find-us' payload: source clips (legs), decision-point cues on the realtime walk timeline, outro, and optional music. Set compositionId 'DirectionsWalkthrough' (or objective 'directions')."
228
242
  )
@@ -241,6 +255,9 @@ var editBriefShape = {
241
255
  ),
242
256
  publishTarget: z.enum(PUBLISH_TARGETS).optional().describe(
243
257
  "Updated target social platform. Distribution metadata only - does not trigger a re-render."
258
+ ),
259
+ voiceId: z.string().optional().describe(
260
+ "Updated TTS narrator voice ID. Triggers a re-render with the new voice."
244
261
  )
245
262
  };
246
263
 
@@ -258,7 +275,7 @@ function registerTools(server) {
258
275
  "list_jobs",
259
276
  {
260
277
  title: "List jobs",
261
- description: "List recent video jobs for the current organization (newest first).",
278
+ description: "List recent video jobs for the current organization (newest first). Start here to discover job IDs; for one job's full detail use get_job_status.",
262
279
  inputSchema: {
263
280
  limit: z2.number().int().min(1).max(50).default(10).describe("Number of jobs to return (default 10, max 50)"),
264
281
  status: z2.enum([
@@ -284,7 +301,7 @@ function registerTools(server) {
284
301
  "get_job_status",
285
302
  {
286
303
  title: "Get job status",
287
- description: "Get detailed status for a job: runs, artifacts, verifications, plus the current video and thumbnail URLs.",
304
+ description: "Get detailed status for a job: runs, artifacts, verifications, plus the current video and thumbnail URLs. The main polling target after create_video_brief or edit_video_brief; for post-publish engagement numbers use get_job_metrics instead.",
288
305
  inputSchema: { jobId: uuid("The job ID to check") },
289
306
  annotations: READ_ONLY
290
307
  },
@@ -294,7 +311,7 @@ function registerTools(server) {
294
311
  "get_video_state",
295
312
  {
296
313
  title: "Get video state",
297
- description: "Get the materialized video state for a job (composition decisions: scenes, duration, aspect ratio, etc.).",
314
+ description: "Get the materialized video state for a job (composition decisions: scenes, duration, aspect ratio, etc.). Use it to inspect what the video contains; for pipeline progress and video URLs use get_job_status.",
298
315
  inputSchema: { jobId: uuid("The job ID") },
299
316
  annotations: READ_ONLY
300
317
  },
@@ -306,7 +323,7 @@ function registerTools(server) {
306
323
  "get_job_metrics",
307
324
  {
308
325
  title: "Get job metrics",
309
- description: "Get the latest platform engagement metric snapshots for a published job (newest first). Read-only.",
326
+ description: "Get the latest platform engagement metric snapshots for a published job (newest first). Read-only. Only meaningful after publish_job; for render progress use get_job_status.",
310
327
  inputSchema: {
311
328
  jobId: uuid("The job ID"),
312
329
  limit: z2.number().int().min(1).max(20).default(10).describe("Max metric snapshots (default 10, max 20)")
@@ -323,7 +340,7 @@ function registerTools(server) {
323
340
  "get_cost_summary",
324
341
  {
325
342
  title: "Get cost summary",
326
- description: "Query production infrastructure costs (Lambda, RunPod, R2, WaveSpeed, PoYo), optionally with reconciliation drift.",
343
+ description: "Query production infrastructure costs (Lambda, RunPod, R2, WaveSpeed, PoYo), optionally with reconciliation drift. This is spend data, not engagement \u2014 for a published job's audience numbers use get_job_metrics.",
327
344
  inputSchema: {
328
345
  since: z2.string().optional().describe("ISO date \u2014 only include events after this date"),
329
346
  provider: z2.enum(["runpod", "lambda", "r2", "wavespeed", "poyo", "all"]).default("all").describe("Filter by provider"),
@@ -343,7 +360,7 @@ function registerTools(server) {
343
360
  "create_video_brief",
344
361
  {
345
362
  title: "Create video brief",
346
- description: "Create a new video job from a structured brief and trigger the render pipeline. Returns the job and run IDs.",
363
+ description: "Create a new video job from a structured brief and trigger the render pipeline. Returns the job and run IDs immediately; rendering continues asynchronously (typically a few minutes) \u2014 poll get_job_status until draft_ready. Requires a key with write scope. To change an existing job, use edit_video_brief instead of creating a duplicate.",
347
364
  inputSchema: createBriefShape,
348
365
  annotations: SAFE_WRITE
349
366
  },
@@ -353,7 +370,7 @@ function registerTools(server) {
353
370
  "edit_video_brief",
354
371
  {
355
372
  title: "Edit video brief",
356
- description: "Edit an existing job's brief (only provided fields change). Changing the script, caption, title, lessonTitle, objective, steps, scenes or aspectRatio triggers a re-render and returns the new run ID; objective also re-routes the composition. Changing only publishTarget updates the job's target platform without re-rendering.",
373
+ description: "Edit an existing job's brief (only provided fields change). Changing the script, caption, title, lessonTitle, objective, steps, scenes, aspectRatio or voiceId triggers a re-render and returns the new run ID; objective also re-routes the composition. Changing only publishTarget updates the job's target platform without re-rendering. For a brand-new video use create_video_brief.",
357
374
  inputSchema: editBriefShape,
358
375
  annotations: SAFE_WRITE
359
376
  },
@@ -368,7 +385,7 @@ function registerTools(server) {
368
385
  "approve_job",
369
386
  {
370
387
  title: "Approve job",
371
- description: "Approve a rendered job so it becomes publishable (draft_ready/awaiting_review/needs_changes -> approved) and revoke active review links.",
388
+ description: "Approve a rendered job so it becomes publishable (draft_ready/awaiting_review/needs_changes -> approved) and revoke active review links. Required before publish_job will accept the job.",
372
389
  inputSchema: { jobId: uuid("The job ID to approve") },
373
390
  annotations: {
374
391
  readOnlyHint: false,
@@ -386,7 +403,7 @@ function registerTools(server) {
386
403
  "publish_job",
387
404
  {
388
405
  title: "Publish job",
389
- description: "Publish an APPROVED job to its connected social destination via the gated publish API. All production gates run (paid plan, ownership, abuse, QA, disclosure, destination, rights, moderation). For YouTube pass youtubePrivacyStatus:'private' for safe runs.",
406
+ description: "Publish an APPROVED job to its connected social destination via the gated publish API. All production gates run (paid plan, ownership, abuse, QA, disclosure, destination, rights, moderation). Requires a key with publish scope; the post goes live on the external platform and cannot be recalled by the API. For YouTube pass youtubePrivacyStatus:'private' for safe runs.",
390
407
  inputSchema: {
391
408
  jobId: uuid("The approved job to publish"),
392
409
  youtubePrivacyStatus: z2.enum(["private", "unlisted", "public"]).optional().describe("YouTube only. Use 'private' for safe dogfood runs."),
@@ -461,7 +478,7 @@ function registerTools(server) {
461
478
  // package.json
462
479
  var package_default = {
463
480
  name: "@instavar/mcp-server",
464
- version: "0.2.1",
481
+ version: "0.3.0",
465
482
  mcpName: "com.instavar/mcp-server",
466
483
  description: "Instavar Studio MCP server \u2014 drive the full video create\u2192render\u2192approve\u2192publish\u2192metrics workflow from Claude Code or Codex with an API key.",
467
484
  type: "module",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instavar/mcp-server",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "mcpName": "com.instavar/mcp-server",
5
5
  "description": "Instavar Studio MCP server — drive the full video create→render→approve→publish→metrics workflow from Claude Code or Codex with an API key.",
6
6
  "type": "module",