@dynamic-mockups/mcp 1.0.2 → 1.0.4

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/package.json +3 -3
  3. package/src/index.js +406 -92
package/README.md CHANGED
@@ -156,4 +156,4 @@ The server returns clear error messages for common issues:
156
156
 
157
157
  ## License
158
158
 
159
- MIT
159
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynamic-mockups/mcp",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Official Dynamic Mockups MCP Server - Generate product mockups with AI assistants",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -37,8 +37,8 @@
37
37
  "dependencies": {
38
38
  "@modelcontextprotocol/sdk": "^1.0.0",
39
39
  "axios": "^1.6.0",
40
- "express": "^4.21.0",
41
- "cors": "^2.8.5"
40
+ "cors": "^2.8.5",
41
+ "express": "^4.21.0"
42
42
  },
43
43
  "engines": {
44
44
  "node": ">=18.0.0"
package/src/index.js CHANGED
@@ -80,8 +80,8 @@ const API_KNOWLEDGE_BASE = {
80
80
  // =============================================================================
81
81
 
82
82
  const server = new Server(
83
- { name: SERVER_NAME, version: SERVER_VERSION },
84
- { capabilities: { tools: {} } }
83
+ { name: SERVER_NAME, version: SERVER_VERSION },
84
+ { capabilities: { tools: {} } }
85
85
  );
86
86
 
87
87
  // =============================================================================
@@ -115,11 +115,11 @@ function createApiClient(apiKey) {
115
115
  function validateApiKey(apiKey) {
116
116
  if (!apiKey) {
117
117
  return ResponseFormatter.error(
118
- "API key not configured",
119
- {
120
- solution: "Provide your Dynamic Mockups API key. For HTTP transport, use the Authorization header (Bearer token). For stdio transport, set the DYNAMIC_MOCKUPS_API_KEY environment variable.",
121
- get_key_at: "https://app.dynamicmockups.com/dashboard-api",
122
- }
118
+ "API key not configured",
119
+ {
120
+ solution: "Provide your Dynamic Mockups API key. For HTTP transport, use the Authorization header (Bearer token). For stdio transport, set the DYNAMIC_MOCKUPS_API_KEY environment variable.",
121
+ get_key_at: "https://app.dynamicmockups.com/dashboard-api",
122
+ }
123
123
  );
124
124
  }
125
125
  return null;
@@ -157,210 +157,377 @@ function getApiKey(extra) {
157
157
  // Tool Definitions
158
158
  // =============================================================================
159
159
 
160
+ // =============================================================================
161
+ // Tool Selection Guide (for LLM understanding)
162
+ // =============================================================================
163
+ //
164
+ // WORKFLOW FOR RENDERING MOCKUPS:
165
+ // 1. Call get_mockups to find available templates (returns mockup UUIDs AND smart_object UUIDs)
166
+ // 2. Use create_render (single) or create_batch_render (multiple) to generate images
167
+ // Note: get_mockups returns all data needed to render - no need to call get_mockup_by_uuid first!
168
+ //
169
+ // WHEN TO USE EACH TOOL:
170
+ // - get_api_info: First call when user asks about limits, pricing, or capabilities
171
+ // - get_catalogs: When user wants to see their workspace organization
172
+ // - get_collections: When user wants to browse mockup groups or find mockups by category
173
+ // - get_mockups: PRIMARY tool - lists templates WITH smart_object UUIDs ready for rendering
174
+ // - get_mockup_by_uuid: Only when user needs ONE specific template (already has UUID)
175
+ // - create_render: For generating 1 mockup image
176
+ // - create_batch_render: For generating 2+ mockup images (more efficient)
177
+ // - export_print_files: When user needs production-ready files with specific DPI
178
+ // - upload_psd: When user wants to add their own PSD mockup template
179
+ // - delete_psd: When user wants to remove an uploaded PSD
180
+ // - create_collection: When user wants to organize mockups into groups
181
+ //
182
+ // =============================================================================
183
+
160
184
  const tools = [
161
- // Knowledge Base Tool
185
+ // ─────────────────────────────────────────────────────────────────────────────
186
+ // KNOWLEDGE BASE TOOL
187
+ // ─────────────────────────────────────────────────────────────────────────────
162
188
  {
163
189
  name: "get_api_info",
164
- description: "Get Dynamic Mockups API information including billing, rate limits, supported formats, and best practices. Use this to understand API capabilities and constraints.",
190
+ description: `Get Dynamic Mockups API knowledge base including billing, rate limits, supported formats, and best practices.
191
+
192
+ WHEN TO USE: Call this FIRST when user asks about:
193
+ - Pricing, credits, or billing
194
+ - Rate limits or API constraints
195
+ - Supported file formats (input/output)
196
+ - Best practices for rendering
197
+ - How to contact support
198
+
199
+ This tool does NOT require an API call - returns cached knowledge instantly.`,
165
200
  inputSchema: {
166
201
  type: "object",
167
202
  properties: {
168
203
  topic: {
169
204
  type: "string",
170
205
  enum: ["all", "billing", "rate_limits", "formats", "best_practices", "support"],
171
- description: "Specific topic to get info about, or 'all' for complete knowledge base",
206
+ description: "Specific topic to retrieve. Use 'all' for complete knowledge base, or select specific topic for focused information.",
172
207
  },
173
208
  },
174
209
  },
175
210
  },
176
211
 
177
- // Catalog Tools
212
+ // ─────────────────────────────────────────────────────────────────────────────
213
+ // CATALOG & ORGANIZATION TOOLS
214
+ // ─────────────────────────────────────────────────────────────────────────────
178
215
  {
179
216
  name: "get_catalogs",
180
- description: "Retrieve all available catalogs. Catalogs are top-level containers for organizing collections and mockups.",
217
+ description: `Retrieve all available catalogs for the authenticated user.
218
+
219
+ API: GET /catalogs
220
+
221
+ WHEN TO USE: When user wants to:
222
+ - See their workspace organization structure
223
+ - Find a specific catalog UUID for filtering collections/mockups
224
+ - Understand how their mockups are organized
225
+
226
+ Catalogs are TOP-LEVEL containers that hold collections. Each catalog has a UUID, name, and type (custom or default).
227
+
228
+ RETURNS: Array of catalogs with uuid, name, type, created_at fields.`,
181
229
  inputSchema: {
182
230
  type: "object",
183
231
  properties: {},
184
232
  },
185
233
  },
186
-
187
- // Collection Tools
188
234
  {
189
235
  name: "get_collections",
190
- description: "Retrieve collections, optionally filtered by catalog. Collections group related mockups together.",
236
+ description: `Retrieve collections with optional filtering by catalog.
237
+
238
+ API: GET /collections
239
+
240
+ WHEN TO USE: When user wants to:
241
+ - Browse available mockup groups/categories
242
+ - Find mockups organized by product type (e.g., "T-shirts", "Mugs")
243
+ - Get a collection UUID to filter mockups
244
+
245
+ Collections GROUP related mockups together within a catalog. By default, only returns collections from the default catalog.
246
+
247
+ RETURNS: Array of collections with uuid, name, mockup_count, created_at fields.`,
191
248
  inputSchema: {
192
249
  type: "object",
193
250
  properties: {
194
251
  catalog_uuid: {
195
252
  type: "string",
196
- description: "Filter collections by catalog UUID",
253
+ description: "Filter collections by specific catalog UUID. Get catalog UUIDs from get_catalogs.",
197
254
  },
198
255
  include_all_catalogs: {
199
256
  type: "boolean",
200
- description: "Include collections from all catalogs (default: false, returns only default catalog)",
257
+ description: "Set to true to include collections from ALL catalogs. Default: false (only default catalog).",
201
258
  },
202
259
  },
203
260
  },
204
261
  },
205
262
  {
206
263
  name: "create_collection",
207
- description: "Create a new collection to organize mockups",
264
+ description: `Create a new collection to organize mockups.
265
+
266
+ API: POST /collections
267
+
268
+ WHEN TO USE: When user wants to:
269
+ - Create a new group/category for mockups
270
+ - Organize mockups by project, client, or product type
271
+
272
+ RETURNS: The created collection with uuid, name, and metadata.`,
208
273
  inputSchema: {
209
274
  type: "object",
210
275
  properties: {
211
276
  name: {
212
277
  type: "string",
213
- description: "Name for the new collection",
278
+ description: "Name for the new collection (e.g., 'Summer 2025 T-shirts', 'Client ABC Mockups').",
214
279
  },
215
280
  catalog_uuid: {
216
281
  type: "string",
217
- description: "Catalog UUID to create collection in (uses default catalog if not specified)",
282
+ description: "Optional catalog UUID to place this collection in. If omitted, uses the default catalog.",
218
283
  },
219
284
  },
220
285
  required: ["name"],
221
286
  },
222
287
  },
223
288
 
224
- // Mockup Tools
289
+ // ─────────────────────────────────────────────────────────────────────────────
290
+ // MOCKUP DISCOVERY TOOLS
291
+ // ─────────────────────────────────────────────────────────────────────────────
225
292
  {
226
293
  name: "get_mockups",
227
- description: "Retrieve mockups from My Templates with optional filtering. Returns mockup UUIDs needed for rendering.",
294
+ description: `Retrieve mockups from My Templates with optional filtering. This is the PRIMARY tool for discovering mockups.
295
+
296
+ API: GET /mockups
297
+
298
+ WHEN TO USE: When user wants to:
299
+ - List all available mockup templates
300
+ - Search for mockups by name
301
+ - Find mockups in a specific collection or catalog
302
+ - Get mockup data needed for rendering
303
+
304
+ IMPORTANT: This returns EVERYTHING needed to render - both mockup UUIDs AND smart_object UUIDs. You do NOT need to call get_mockup_by_uuid before rendering.
305
+
306
+ WORKFLOW: get_mockups → create_render (that's it!)
307
+
308
+ RETURNS: Array of mockups, each containing:
309
+ - uuid: mockup template UUID (use in create_render)
310
+ - name, thumbnail
311
+ - smart_objects[]: array with uuid (use in smart_objects param), name, size, position, print_area_presets[]
312
+ - text_layers[]: uuid, name
313
+ - collections[]`,
228
314
  inputSchema: {
229
315
  type: "object",
230
316
  properties: {
231
317
  catalog_uuid: {
232
318
  type: "string",
233
- description: "Filter by catalog UUID",
319
+ description: "Filter mockups by catalog UUID. Get from get_catalogs.",
234
320
  },
235
321
  collection_uuid: {
236
322
  type: "string",
237
- description: "Filter by collection UUID",
323
+ description: "Filter mockups by collection UUID. Get from get_collections.",
238
324
  },
239
325
  include_all_catalogs: {
240
326
  type: "boolean",
241
- description: "Include mockups from all catalogs (default: false)",
327
+ description: "Set to true to include mockups from ALL catalogs. Default: false (only default catalog).",
242
328
  },
243
329
  name: {
244
330
  type: "string",
245
- description: "Filter mockups by name (partial match)",
331
+ description: "Filter mockups by name (partial match, case-insensitive). E.g., 'mug' finds 'Coffee Mug', 'Beer Mug'.",
246
332
  },
247
333
  },
248
334
  },
249
335
  },
250
336
  {
251
337
  name: "get_mockup_by_uuid",
252
- description: "Get detailed information about a specific mockup including its smart objects and configuration",
338
+ description: `Get detailed information about a SINGLE specific mockup by its UUID.
339
+
340
+ API: GET /mockup/{uuid}
341
+
342
+ WHEN TO USE: Only in specific scenarios:
343
+ - User already has a mockup UUID and wants details about that ONE template
344
+ - User provided a specific mockup UUID directly
345
+ - Need to refresh data for a single known mockup
346
+
347
+ NOT REQUIRED for rendering! The get_mockups tool already returns smart_object UUIDs. Only use this when you need info about ONE specific mockup and don't need to list/browse.
348
+
349
+ RETURNS: Single mockup with:
350
+ - uuid, name, thumbnail
351
+ - smart_objects[]: uuid, name, size (width/height), position (top/left), print_area_presets[]
352
+ - text_layers[]: uuid, name
353
+ - collections[], thumbnails[]`,
253
354
  inputSchema: {
254
355
  type: "object",
255
356
  properties: {
256
357
  uuid: {
257
358
  type: "string",
258
- description: "The mockup UUID",
359
+ description: "The mockup UUID. Get this from get_mockups response.",
259
360
  },
260
361
  },
261
362
  required: ["uuid"],
262
363
  },
263
364
  },
264
365
 
265
- // Render Tools
366
+ // ─────────────────────────────────────────────────────────────────────────────
367
+ // RENDER TOOLS
368
+ // ─────────────────────────────────────────────────────────────────────────────
266
369
  {
267
370
  name: "create_render",
268
- description: "Render a single mockup with design assets. Costs 1 credit per render. For multiple renders, use create_batch_render instead.",
371
+ description: `Render a SINGLE mockup with design assets. Returns an image URL.
372
+
373
+ API: POST /renders
374
+ COST: 1 credit per render
375
+
376
+ WHEN TO USE: When user wants to generate exactly ONE mockup image.
377
+ For 2+ images, use create_batch_render instead (more efficient, same cost).
378
+
379
+ PREREQUISITES: Call get_mockups first - it returns both mockup_uuid AND smart_object uuids needed for rendering.
380
+
381
+ SMART OBJECT OPTIONS:
382
+ - asset.url: Public URL to design image (jpg, jpeg, png, webp, gif)
383
+ - asset.fit: 'stretch' | 'contain' | 'cover' - how image fits the area
384
+ - asset.size: {width, height} - custom dimensions in pixels
385
+ - asset.position: {top, left} - custom positioning
386
+ - asset.rotate: rotation angle in degrees (0-360)
387
+ - color: hex color overlay (e.g., '#FF0000' for red)
388
+ - pattern: {enabled: true, scale_percent: 60} - repeat pattern mode
389
+ - blending_mode: Photoshop blend modes (NORMAL, MULTIPLY, SCREEN, OVERLAY, etc.)
390
+ - adjustment_layers: {brightness, contrast, opacity, saturation, vibrance, blur}
391
+ - print_area_preset_uuid: auto-position using preset (get from mockup details)
392
+
393
+ RETURNS: {export_label, export_path} - export_path is the rendered image URL (valid 24h).`,
269
394
  inputSchema: {
270
395
  type: "object",
271
396
  properties: {
272
397
  mockup_uuid: {
273
398
  type: "string",
274
- description: "UUID of the mockup template to render",
399
+ description: "UUID of the mockup template to render. Get from get_mockups.",
275
400
  },
276
401
  smart_objects: {
277
402
  type: "array",
278
- description: "Smart objects configuration with design assets",
403
+ description: "Array of smart object configurations. Each mockup has one or more smart objects where you place your design.",
279
404
  items: {
280
405
  type: "object",
406
+ required: ["uuid"],
281
407
  properties: {
282
408
  uuid: {
283
409
  type: "string",
284
- description: "Smart object UUID (get from mockup details)",
410
+ description: "REQUIRED. Smart object UUID. Get from get_mockups response.",
285
411
  },
286
412
  asset: {
287
413
  type: "object",
288
- description: "Design asset configuration",
414
+ description: "Design asset to place in this smart object. Provide at minimum the url field.",
415
+ required: ["url"],
289
416
  properties: {
290
417
  url: {
291
418
  type: "string",
292
- description: "URL to the design image (jpg, jpeg, png, webp, gif)",
419
+ description: "REQUIRED. Public URL to the design image. Supported: jpg, jpeg, png, webp, gif.",
293
420
  },
294
421
  fit: {
295
422
  type: "string",
296
423
  enum: ["stretch", "contain", "cover"],
297
- description: "How to fit the asset in the smart object area",
424
+ description: "Optional. How the asset fits: 'stretch' distorts to fill, 'contain' fits inside with padding, 'cover' fills and crops. Default: contain.",
298
425
  },
299
426
  size: {
300
427
  type: "object",
428
+ description: "Optional. Custom asset size in pixels. Only use if you need specific dimensions.",
301
429
  properties: {
302
- width: { type: "integer" },
303
- height: { type: "integer" },
430
+ width: { type: "integer", description: "Width in pixels" },
431
+ height: { type: "integer", description: "Height in pixels" },
304
432
  },
305
433
  },
306
434
  position: {
307
435
  type: "object",
436
+ description: "Optional. Custom asset position relative to smart object. Only use for manual positioning.",
308
437
  properties: {
309
- top: { type: "integer" },
310
- left: { type: "integer" },
438
+ top: { type: "integer", description: "Top offset in pixels" },
439
+ left: { type: "integer", description: "Left offset in pixels" },
311
440
  },
312
441
  },
313
442
  rotate: {
314
443
  type: "number",
315
- description: "Rotation angle in degrees",
444
+ description: "Optional. Rotation angle in degrees (0-360).",
316
445
  },
317
446
  },
318
447
  },
319
448
  color: {
320
449
  type: "string",
321
- description: "Color overlay in hex format (e.g., #FF0000)",
450
+ description: "Optional. Color overlay in hex format (e.g., '#FF0000' for red). Use for solid color fills instead of an image.",
451
+ },
452
+ pattern: {
453
+ type: "object",
454
+ description: "Optional. Repeat the asset as a seamless pattern. Only use when pattern effect is needed.",
455
+ properties: {
456
+ enabled: {
457
+ type: "boolean",
458
+ description: "Set to true to enable pattern mode.",
459
+ },
460
+ scale_percent: {
461
+ type: "number",
462
+ description: "Pattern scale as percentage (e.g., 60 = 60% of original size).",
463
+ },
464
+ },
465
+ },
466
+ blending_mode: {
467
+ type: "string",
468
+ enum: [
469
+ "NORMAL", "DISSOLVE", "DARKEN", "MULTIPLY", "COLOR_BURN", "LINEAR_BURN", "DARKER_COLOR",
470
+ "LIGHTEN", "SCREEN", "COLOR_DODGE", "LINEAR_DODGE", "LIGHTER_COLOR",
471
+ "OVERLAY", "SOFT_LIGHT", "HARD_LIGHT", "VIVID_LIGHT", "LINEAR_LIGHT", "PIN_LIGHT", "HARD_MIX",
472
+ "DIFFERENCE", "EXCLUSION", "SUBTRACT", "DIVIDE", "HUE", "SATURATION", "COLOR", "LUMINOSITY"
473
+ ],
474
+ description: "Optional. Photoshop blending mode. Default: NORMAL. Use MULTIPLY for printing on colored surfaces.",
475
+ },
476
+ adjustment_layers: {
477
+ type: "object",
478
+ description: "Optional. Image adjustments. Only use when user needs specific image corrections.",
479
+ properties: {
480
+ brightness: { type: "integer", description: "Brightness: -150 to 150" },
481
+ contrast: { type: "integer", description: "Contrast: -100 to 100" },
482
+ opacity: { type: "integer", description: "Opacity: 0 to 100" },
483
+ saturation: { type: "integer", description: "Saturation: -100 to 100" },
484
+ vibrance: { type: "integer", description: "Vibrance: -100 to 100" },
485
+ blur: { type: "integer", description: "Blur: 0 to 100" },
486
+ },
322
487
  },
323
488
  print_area_preset_uuid: {
324
489
  type: "string",
325
- description: "Print area preset UUID for automatic positioning",
490
+ description: "Optional. UUID of print area preset for automatic positioning. Alternative to manual size/position.",
326
491
  },
327
492
  },
328
493
  },
329
494
  },
495
+ text_layers: {
496
+ type: "array",
497
+ description: "Optional. Customize text layers in the mockup (if the mockup has text layers).",
498
+ items: {
499
+ type: "object",
500
+ required: ["uuid", "text"],
501
+ properties: {
502
+ uuid: { type: "string", description: "REQUIRED. Text layer UUID. Get from get_mockups response." },
503
+ text: { type: "string", description: "REQUIRED. Text content to display." },
504
+ font_family: { type: "string", description: "Optional. Font family name (e.g., 'Arial', 'Helvetica')." },
505
+ font_size: { type: "number", description: "Optional. Font size in pixels." },
506
+ font_color: { type: "string", description: "Optional. Text color in hex format (e.g., '#FF5733')." },
507
+ },
508
+ },
509
+ },
330
510
  export_label: {
331
511
  type: "string",
332
- description: "Label for the exported image (appears in filename)",
512
+ description: "Optional. Custom label for the exported image. Appears in the filename.",
333
513
  },
334
514
  export_options: {
335
515
  type: "object",
516
+ description: "Optional. Output image settings. If omitted, uses defaults (jpg, 1000px, view mode).",
336
517
  properties: {
337
518
  image_format: {
338
519
  type: "string",
339
520
  enum: ["jpg", "png", "webp"],
340
- description: "Output image format (default: jpg)",
521
+ description: "Optional. Output format. Default: jpg. Use png for transparency, webp for best compression.",
341
522
  },
342
523
  image_size: {
343
524
  type: "integer",
344
- description: "Output image size in pixels (default: 1000)",
525
+ description: "Optional. Output image size in pixels (width). Default: 1000.",
345
526
  },
346
527
  mode: {
347
528
  type: "string",
348
529
  enum: ["view", "download"],
349
- description: "URL mode - 'view' for browser display, 'download' for attachment",
350
- },
351
- },
352
- },
353
- text_layers: {
354
- type: "array",
355
- description: "Text layer customizations",
356
- items: {
357
- type: "object",
358
- properties: {
359
- uuid: { type: "string", description: "Text layer UUID" },
360
- text: { type: "string", description: "Text content" },
361
- font_family: { type: "string" },
362
- font_size: { type: "number" },
363
- font_color: { type: "string", description: "Hex color code" },
530
+ description: "Optional. Default: 'view' for browser display. Use 'download' for attachment header.",
364
531
  },
365
532
  },
366
533
  },
@@ -370,50 +537,124 @@ const tools = [
370
537
  },
371
538
  {
372
539
  name: "create_batch_render",
373
- description: "Render multiple mockups in a single request. RECOMMENDED for rendering more than one image - more efficient and faster than individual renders. Costs 1 credit per image.",
540
+ description: `Render MULTIPLE mockups in a single request. Returns array of image URLs.
541
+
542
+ API: POST /renders/batch
543
+ COST: 1 credit per image
544
+
545
+ WHEN TO USE: When user wants to generate 2 or more mockup images.
546
+ MORE EFFICIENT than calling create_render multiple times - single API call, faster processing.
547
+
548
+ Use cases:
549
+ - Render same design on multiple mockup templates
550
+ - Render different designs on different mockups
551
+ - Generate a product catalog with many images
552
+
553
+ PREREQUISITES: Call get_mockups first - it returns both mockup_uuid AND smart_object uuids for all templates.
554
+
555
+ RETURNS: {total_renders, successful_renders, failed_renders, renders[]} where each render has {status, export_path, export_label, mockup_uuid}.`,
374
556
  inputSchema: {
375
557
  type: "object",
376
558
  properties: {
377
559
  renders: {
378
560
  type: "array",
379
- description: "Array of render configurations",
561
+ description: "REQUIRED. Array of render configurations. Each item renders one mockup image.",
380
562
  items: {
381
563
  type: "object",
564
+ required: ["mockup_uuid", "smart_objects"],
382
565
  properties: {
383
566
  mockup_uuid: {
384
567
  type: "string",
385
- description: "UUID of the mockup template",
568
+ description: "REQUIRED. UUID of the mockup template. Get from get_mockups.",
386
569
  },
387
570
  smart_objects: {
388
571
  type: "array",
389
- description: "Smart objects configuration (same as create_render)",
572
+ description: "REQUIRED. Smart objects configuration. Same structure as create_render.",
573
+ items: {
574
+ type: "object",
575
+ required: ["uuid"],
576
+ properties: {
577
+ uuid: { type: "string", description: "REQUIRED. Smart object UUID from get_mockups." },
578
+ asset: {
579
+ type: "object",
580
+ required: ["url"],
581
+ properties: {
582
+ url: { type: "string", description: "REQUIRED. Public URL to design image." },
583
+ fit: { type: "string", enum: ["stretch", "contain", "cover"], description: "Optional. Default: contain." },
584
+ size: { type: "object", description: "Optional.", properties: { width: { type: "integer" }, height: { type: "integer" } } },
585
+ position: { type: "object", description: "Optional.", properties: { top: { type: "integer" }, left: { type: "integer" } } },
586
+ rotate: { type: "number", description: "Optional." },
587
+ },
588
+ },
589
+ color: { type: "string", description: "Optional. Hex color overlay." },
590
+ pattern: {
591
+ type: "object",
592
+ description: "Optional.",
593
+ properties: {
594
+ enabled: { type: "boolean" },
595
+ scale_percent: { type: "number" },
596
+ },
597
+ },
598
+ blending_mode: {
599
+ type: "string",
600
+ description: "Optional. Default: NORMAL.",
601
+ enum: ["NORMAL", "DISSOLVE", "DARKEN", "MULTIPLY", "COLOR_BURN", "LINEAR_BURN", "DARKER_COLOR", "LIGHTEN", "SCREEN", "COLOR_DODGE", "LINEAR_DODGE", "LIGHTER_COLOR", "OVERLAY", "SOFT_LIGHT", "HARD_LIGHT", "VIVID_LIGHT", "LINEAR_LIGHT", "PIN_LIGHT", "HARD_MIX", "DIFFERENCE", "EXCLUSION", "SUBTRACT", "DIVIDE", "HUE", "SATURATION", "COLOR", "LUMINOSITY"],
602
+ },
603
+ adjustment_layers: {
604
+ type: "object",
605
+ description: "Optional.",
606
+ properties: {
607
+ brightness: { type: "integer" },
608
+ contrast: { type: "integer" },
609
+ opacity: { type: "integer" },
610
+ saturation: { type: "integer" },
611
+ vibrance: { type: "integer" },
612
+ blur: { type: "integer" },
613
+ },
614
+ },
615
+ print_area_preset_uuid: { type: "string", description: "Optional." },
616
+ },
617
+ },
390
618
  },
391
619
  text_layers: {
392
620
  type: "array",
393
- description: "Text layer customizations",
621
+ description: "Optional. Text layer customizations.",
622
+ items: {
623
+ type: "object",
624
+ required: ["uuid", "text"],
625
+ properties: {
626
+ uuid: { type: "string", description: "REQUIRED." },
627
+ text: { type: "string", description: "REQUIRED." },
628
+ font_family: { type: "string", description: "Optional." },
629
+ font_size: { type: "number", description: "Optional." },
630
+ font_color: { type: "string", description: "Optional." },
631
+ },
632
+ },
394
633
  },
395
634
  export_label: {
396
635
  type: "string",
397
- description: "Label for this specific render",
636
+ description: "Optional. Label for this specific render in the batch.",
398
637
  },
399
638
  },
400
- required: ["mockup_uuid", "smart_objects"],
401
639
  },
402
640
  },
403
641
  export_options: {
404
642
  type: "object",
405
- description: "Export options applied to all renders in the batch",
643
+ description: "Optional. Export options applied to ALL renders in the batch. If omitted, uses defaults.",
406
644
  properties: {
407
645
  image_format: {
408
646
  type: "string",
409
647
  enum: ["jpg", "png", "webp"],
648
+ description: "Optional. Output format for all renders. Default: jpg.",
410
649
  },
411
650
  image_size: {
412
651
  type: "integer",
652
+ description: "Optional. Output image size in pixels for all renders. Default: 1000.",
413
653
  },
414
654
  mode: {
415
655
  type: "string",
416
656
  enum: ["view", "download"],
657
+ description: "Optional. 'view' or 'download' mode for all renders. Default: view.",
417
658
  },
418
659
  },
419
660
  },
@@ -423,33 +664,80 @@ const tools = [
423
664
  },
424
665
  {
425
666
  name: "export_print_files",
426
- description: "Export high-resolution print files for production. Supports custom DPI settings.",
667
+ description: `Export high-resolution print files for production use.
668
+
669
+ API: POST /renders/print-files
670
+ COST: 1 credit per each print file
671
+
672
+ WHEN TO USE: When user needs:
673
+ - Production-ready files for printing
674
+ - High DPI output (e.g., 300 DPI for professional printing)
675
+ - Print files for each smart object separately
676
+
677
+ Unlike create_render which outputs the full mockup, this exports the design as it will appear when printed - useful for sending to print shops.
678
+
679
+ RETURNS: {print_files[]} where each has {export_path, smart_object_uuid, smart_object_name}.`,
427
680
  inputSchema: {
428
681
  type: "object",
429
682
  properties: {
430
683
  mockup_uuid: {
431
684
  type: "string",
432
- description: "UUID of the mockup template",
685
+ description: "REQUIRED. UUID of the mockup template. Get from get_mockups.",
433
686
  },
434
687
  smart_objects: {
435
688
  type: "array",
436
- description: "Smart objects configuration",
689
+ description: "REQUIRED. Smart objects configuration. Same structure as create_render.",
690
+ items: {
691
+ type: "object",
692
+ required: ["uuid"],
693
+ properties: {
694
+ uuid: { type: "string", description: "REQUIRED. Smart object UUID from get_mockups." },
695
+ asset: {
696
+ type: "object",
697
+ required: ["url"],
698
+ properties: {
699
+ url: { type: "string", description: "REQUIRED. Public URL to design image." },
700
+ fit: { type: "string", enum: ["stretch", "contain", "cover"], description: "Optional. Default: contain." },
701
+ size: { type: "object", description: "Optional.", properties: { width: { type: "integer" }, height: { type: "integer" } } },
702
+ position: { type: "object", description: "Optional.", properties: { top: { type: "integer" }, left: { type: "integer" } } },
703
+ rotate: { type: "number", description: "Optional." },
704
+ },
705
+ },
706
+ color: { type: "string", description: "Optional." },
707
+ pattern: { type: "object", description: "Optional.", properties: { enabled: { type: "boolean" }, scale_percent: { type: "number" } } },
708
+ blending_mode: { type: "string", description: "Optional.", enum: ["NORMAL", "DISSOLVE", "DARKEN", "MULTIPLY", "COLOR_BURN", "LINEAR_BURN", "DARKER_COLOR", "LIGHTEN", "SCREEN", "COLOR_DODGE", "LINEAR_DODGE", "LIGHTER_COLOR", "OVERLAY", "SOFT_LIGHT", "HARD_LIGHT", "VIVID_LIGHT", "LINEAR_LIGHT", "PIN_LIGHT", "HARD_MIX", "DIFFERENCE", "EXCLUSION", "SUBTRACT", "DIVIDE", "HUE", "SATURATION", "COLOR", "LUMINOSITY"] },
709
+ adjustment_layers: { type: "object", description: "Optional.", properties: { brightness: { type: "integer" }, contrast: { type: "integer" }, opacity: { type: "integer" }, saturation: { type: "integer" }, vibrance: { type: "integer" }, blur: { type: "integer" } } },
710
+ print_area_preset_uuid: { type: "string", description: "Optional." },
711
+ },
712
+ },
437
713
  },
438
714
  text_layers: {
439
715
  type: "array",
440
- description: "Text layer customizations",
716
+ description: "Optional. Text layer customizations.",
717
+ items: {
718
+ type: "object",
719
+ required: ["uuid", "text"],
720
+ properties: {
721
+ uuid: { type: "string", description: "REQUIRED." },
722
+ text: { type: "string", description: "REQUIRED." },
723
+ font_family: { type: "string", description: "Optional." },
724
+ font_size: { type: "number", description: "Optional." },
725
+ font_color: { type: "string", description: "Optional." },
726
+ },
727
+ },
441
728
  },
442
729
  export_label: {
443
730
  type: "string",
444
- description: "Label for the export",
731
+ description: "Optional. Label for the exported files.",
445
732
  },
446
733
  export_options: {
447
734
  type: "object",
735
+ description: "Optional. Print file export settings.",
448
736
  properties: {
449
- image_format: { type: "string", enum: ["jpg", "png", "webp"] },
450
- image_size: { type: "integer" },
451
- image_dpi: { type: "integer", description: "DPI for print (e.g., 300)" },
452
- mode: { type: "string", enum: ["view", "download"] },
737
+ image_format: { type: "string", enum: ["jpg", "png", "webp"], description: "Optional. Output format. PNG recommended for print." },
738
+ image_size: { type: "integer", description: "Optional. Output size in pixels." },
739
+ image_dpi: { type: "integer", description: "Optional. DPI for print output. Standard: 300 for professional printing, 150 for web-to-print." },
740
+ mode: { type: "string", enum: ["view", "download"], description: "Optional. Default: view." },
453
741
  },
454
742
  },
455
743
  },
@@ -457,41 +745,56 @@ const tools = [
457
745
  },
458
746
  },
459
747
 
460
- // PSD Management Tools
748
+ // ─────────────────────────────────────────────────────────────────────────────
749
+ // PSD MANAGEMENT TOOLS
750
+ // ─────────────────────────────────────────────────────────────────────────────
461
751
  {
462
752
  name: "upload_psd",
463
- description: "Upload a PSD file to create custom mockup templates. The PSD should contain smart object layers.",
753
+ description: `Upload a PSD file to create custom mockup templates.
754
+
755
+ API: POST /psd/upload
756
+
757
+ WHEN TO USE: When user wants to:
758
+ - Add their own PSD mockup template
759
+ - Create custom mockups from their Photoshop files
760
+ - The PSD must contain smart object layers for design placement
761
+
762
+ WORKFLOW:
763
+ 1. Upload PSD with create_after_upload: true to auto-create mockup template
764
+ 2. Or upload PSD first, then manually create mockup template later
765
+
766
+ RETURNS: {uuid, name} of the uploaded PSD file.`,
464
767
  inputSchema: {
465
768
  type: "object",
466
769
  properties: {
467
770
  psd_file_url: {
468
771
  type: "string",
469
- description: "Public URL to the PSD file",
772
+ description: "REQUIRED. Public URL to the PSD file. Must be directly downloadable (not a preview page).",
470
773
  },
471
774
  psd_name: {
472
775
  type: "string",
473
- description: "Name for the uploaded PSD",
776
+ description: "Optional. Custom name for the uploaded PSD. If omitted, uses filename from URL.",
474
777
  },
475
778
  psd_category_id: {
476
779
  type: "integer",
477
- description: "Category ID for organization",
780
+ description: "Optional. Category ID for organizing PSD files.",
478
781
  },
479
782
  mockup_template: {
480
783
  type: "object",
481
- description: "Automatically create a mockup template from the PSD",
784
+ description: "Optional. Settings for automatically creating a mockup template from the PSD.",
482
785
  properties: {
483
786
  create_after_upload: {
484
787
  type: "boolean",
485
- description: "Create mockup template after upload",
788
+ description: "Optional. Set to true to automatically create a mockup template after upload.",
486
789
  },
487
790
  collections: {
488
791
  type: "array",
489
792
  items: { type: "string" },
490
- description: "Collection UUIDs to add the mockup to",
793
+ description: "Optional. Collection UUIDs to add the new mockup to. Get from get_collections.",
491
794
  },
492
795
  catalog_uuid: {
493
796
  type: "string",
494
- description: "Catalog UUID for the mockup",
797
+ description: "Optional. Catalog UUID to add the mockup to. If omitted, uses default catalog.",
495
798
  },
496
799
  },
497
800
  },
@@ -501,17 +804,28 @@ const tools = [
501
804
  },
502
805
  {
503
806
  name: "delete_psd",
504
- description: "Delete a PSD file and optionally all mockups created from it",
807
+ description: `Delete a PSD file and optionally all mockups created from it.
808
+
809
+ API: POST /psd/delete
810
+
811
+ WHEN TO USE: When user wants to:
812
+ - Remove an uploaded PSD file
813
+ - Clean up unused PSD files
814
+ - Optionally remove all mockups derived from the PSD
815
+
816
+ WARNING: If delete_related_mockups is true, all mockups created from this PSD will be permanently deleted.
817
+
818
+ RETURNS: Success confirmation message.`,
505
819
  inputSchema: {
506
820
  type: "object",
507
821
  properties: {
508
822
  psd_uuid: {
509
823
  type: "string",
510
- description: "UUID of the PSD to delete",
824
+ description: "REQUIRED. UUID of the PSD file to delete.",
511
825
  },
512
826
  delete_related_mockups: {
513
827
  type: "boolean",
514
- description: "Also delete all mockups created from this PSD (default: false)",
828
+ description: "Optional. Set to true to also delete all mockups created from this PSD. Default: false (keeps mockups).",
515
829
  },
516
830
  },
517
831
  required: ["psd_uuid"],
@@ -856,8 +1170,8 @@ async function startHttpServer(options = {}) {
856
1170
  if (req.method === "POST" || req.method === "GET") {
857
1171
  // Create a new MCP server instance for this connection
858
1172
  const connectionServer = new Server(
859
- { name: SERVER_NAME, version: SERVER_VERSION },
860
- { capabilities: { tools: {} } }
1173
+ { name: SERVER_NAME, version: SERVER_VERSION },
1174
+ { capabilities: { tools: {} } }
861
1175
  );
862
1176
 
863
1177
  // Register the same handlers