@dynamic-mockups/mcp 1.0.3 → 1.0.5

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