@ourroadmaps/mcp 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +429 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -475,7 +475,8 @@ class ApiClient {
|
|
|
475
475
|
});
|
|
476
476
|
if (!response.ok) {
|
|
477
477
|
const error = await response.json().catch(() => ({ message: response.statusText }));
|
|
478
|
-
|
|
478
|
+
const errorMessage = error.error?.message || error.message || "Unknown error";
|
|
479
|
+
throw new Error(`API Error (${response.status}): ${errorMessage} - Path: ${path}`);
|
|
479
480
|
}
|
|
480
481
|
if (response.status === 204) {
|
|
481
482
|
return;
|
|
@@ -569,9 +570,9 @@ class ApiClient {
|
|
|
569
570
|
return response.data;
|
|
570
571
|
}
|
|
571
572
|
async linkFeatureToRoadmap(featureId, roadmapId) {
|
|
572
|
-
await this.request(`/v1/features/${featureId}/roadmap-
|
|
573
|
+
await this.request(`/v1/features/${featureId}/roadmap-links`, {
|
|
573
574
|
method: "POST",
|
|
574
|
-
body: JSON.stringify({
|
|
575
|
+
body: JSON.stringify({ roadmapId })
|
|
575
576
|
});
|
|
576
577
|
}
|
|
577
578
|
async listIdeas() {
|
|
@@ -734,6 +735,91 @@ class ApiClient {
|
|
|
734
735
|
});
|
|
735
736
|
return response.data;
|
|
736
737
|
}
|
|
738
|
+
async getWireframeUploadUrl(data) {
|
|
739
|
+
const response = await this.request("/v1/wireframes/upload-url", {
|
|
740
|
+
method: "POST",
|
|
741
|
+
body: JSON.stringify(data)
|
|
742
|
+
});
|
|
743
|
+
return response.data;
|
|
744
|
+
}
|
|
745
|
+
async createWireframe(roadmapId, data) {
|
|
746
|
+
const response = await this.request(`/v1/wireframes/roadmaps/${roadmapId}/wireframes`, {
|
|
747
|
+
method: "POST",
|
|
748
|
+
body: JSON.stringify(data)
|
|
749
|
+
});
|
|
750
|
+
return response.data;
|
|
751
|
+
}
|
|
752
|
+
async updateWireframe(id, data) {
|
|
753
|
+
const response = await this.request(`/v1/wireframes/${id}`, {
|
|
754
|
+
method: "PATCH",
|
|
755
|
+
body: JSON.stringify(data)
|
|
756
|
+
});
|
|
757
|
+
return response.data;
|
|
758
|
+
}
|
|
759
|
+
async updateWireframeOutcomes(id, outcomeIds) {
|
|
760
|
+
const response = await this.request(`/v1/wireframes/${id}/outcomes`, {
|
|
761
|
+
method: "POST",
|
|
762
|
+
body: JSON.stringify({ outcomeIds })
|
|
763
|
+
});
|
|
764
|
+
return response.data;
|
|
765
|
+
}
|
|
766
|
+
async deleteWireframe(id) {
|
|
767
|
+
await this.request(`/v1/wireframes/${id}`, {
|
|
768
|
+
method: "DELETE"
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
async getBrainstormUploadUrl(data) {
|
|
772
|
+
const response = await this.request("/v1/brainstorm/upload-url", {
|
|
773
|
+
method: "POST",
|
|
774
|
+
body: JSON.stringify(data)
|
|
775
|
+
});
|
|
776
|
+
return response.data;
|
|
777
|
+
}
|
|
778
|
+
async createBrainstormMedia(roadmapId, data) {
|
|
779
|
+
const response = await this.request(`/v1/brainstorm/roadmaps/${roadmapId}/media`, {
|
|
780
|
+
method: "POST",
|
|
781
|
+
body: JSON.stringify(data)
|
|
782
|
+
});
|
|
783
|
+
return response.data;
|
|
784
|
+
}
|
|
785
|
+
async updateBrainstormMedia(id, data) {
|
|
786
|
+
const response = await this.request(`/v1/brainstorm/media/${id}`, {
|
|
787
|
+
method: "PATCH",
|
|
788
|
+
body: JSON.stringify(data)
|
|
789
|
+
});
|
|
790
|
+
return response.data;
|
|
791
|
+
}
|
|
792
|
+
async deleteBrainstormMedia(id) {
|
|
793
|
+
await this.request(`/v1/brainstorm/media/${id}`, {
|
|
794
|
+
method: "DELETE"
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
async getProductDesignUploadUrl(productId, data) {
|
|
798
|
+
const response = await this.request(`/v1/products/${productId}/design-media/upload-url`, {
|
|
799
|
+
method: "POST",
|
|
800
|
+
body: JSON.stringify(data)
|
|
801
|
+
});
|
|
802
|
+
return response.data;
|
|
803
|
+
}
|
|
804
|
+
async createProductDesignMedia(productId, data) {
|
|
805
|
+
const response = await this.request(`/v1/products/${productId}/design-media`, {
|
|
806
|
+
method: "POST",
|
|
807
|
+
body: JSON.stringify(data)
|
|
808
|
+
});
|
|
809
|
+
return response.data;
|
|
810
|
+
}
|
|
811
|
+
async updateProductDesignMedia(productId, mediaId, data) {
|
|
812
|
+
const response = await this.request(`/v1/products/${productId}/design-media/${mediaId}`, {
|
|
813
|
+
method: "PATCH",
|
|
814
|
+
body: JSON.stringify(data)
|
|
815
|
+
});
|
|
816
|
+
return response.data;
|
|
817
|
+
}
|
|
818
|
+
async deleteProductDesignMedia(productId, mediaId) {
|
|
819
|
+
await this.request(`/v1/products/${productId}/design-media/${mediaId}`, {
|
|
820
|
+
method: "DELETE"
|
|
821
|
+
});
|
|
822
|
+
}
|
|
737
823
|
async updateDesignDescription(roadmapId, description) {
|
|
738
824
|
const response = await this.request(`/v1/designs/roadmaps/${roadmapId}/design`, {
|
|
739
825
|
method: "PATCH",
|
|
@@ -772,6 +858,20 @@ function getApiClient() {
|
|
|
772
858
|
}
|
|
773
859
|
|
|
774
860
|
// src/tools/index.ts
|
|
861
|
+
function inferContentType(filename) {
|
|
862
|
+
const ext = filename.split(".").pop()?.toLowerCase();
|
|
863
|
+
const mapping = {
|
|
864
|
+
png: "image/png",
|
|
865
|
+
jpg: "image/jpeg",
|
|
866
|
+
jpeg: "image/jpeg",
|
|
867
|
+
gif: "image/gif",
|
|
868
|
+
webp: "image/webp",
|
|
869
|
+
mp4: "video/mp4",
|
|
870
|
+
webm: "video/webm",
|
|
871
|
+
mov: "video/quicktime"
|
|
872
|
+
};
|
|
873
|
+
return ext ? mapping[ext] ?? null : null;
|
|
874
|
+
}
|
|
775
875
|
function registerAllTools(server) {
|
|
776
876
|
registerSearchRoadmaps(server);
|
|
777
877
|
registerGetRoadmap(server);
|
|
@@ -813,6 +913,15 @@ function registerAllTools(server) {
|
|
|
813
913
|
registerGetHistorySummary(server);
|
|
814
914
|
registerCreateStatusUpdate(server);
|
|
815
915
|
registerSaveStories(server);
|
|
916
|
+
registerUploadWireframe(server);
|
|
917
|
+
registerUpdateWireframe(server);
|
|
918
|
+
registerDeleteWireframe(server);
|
|
919
|
+
registerUploadBrainstormMedia(server);
|
|
920
|
+
registerUpdateBrainstormMedia(server);
|
|
921
|
+
registerDeleteBrainstormMedia(server);
|
|
922
|
+
registerUploadProductDesignMedia(server);
|
|
923
|
+
registerUpdateProductDesignMedia(server);
|
|
924
|
+
registerDeleteProductDesignMedia(server);
|
|
816
925
|
}
|
|
817
926
|
function registerSearchRoadmaps(server) {
|
|
818
927
|
server.registerTool("search_roadmaps", {
|
|
@@ -2259,6 +2368,323 @@ function registerSaveStories(server) {
|
|
|
2259
2368
|
};
|
|
2260
2369
|
});
|
|
2261
2370
|
}
|
|
2371
|
+
function registerUploadWireframe(server) {
|
|
2372
|
+
server.registerTool("upload_wireframe", {
|
|
2373
|
+
description: "Upload an image to a roadmap item's wireframes. Returns a curl command to execute for the upload, then creates the wireframe record. After running the curl command, the wireframe will be visible in the web app.",
|
|
2374
|
+
inputSchema: {
|
|
2375
|
+
roadmapId: z10.string().describe("The UUID of the roadmap item"),
|
|
2376
|
+
filePath: z10.string().describe("Absolute path to the image file on disk"),
|
|
2377
|
+
description: z10.string().optional().describe("Optional description of the wireframe"),
|
|
2378
|
+
outcomeIds: z10.array(z10.string()).optional().describe("Optional array of PRD outcome IDs this wireframe addresses")
|
|
2379
|
+
}
|
|
2380
|
+
}, async ({
|
|
2381
|
+
roadmapId,
|
|
2382
|
+
filePath,
|
|
2383
|
+
description,
|
|
2384
|
+
outcomeIds
|
|
2385
|
+
}) => {
|
|
2386
|
+
const client2 = getApiClient();
|
|
2387
|
+
const filename = filePath.split("/").pop() || "image.png";
|
|
2388
|
+
const contentType = inferContentType(filename);
|
|
2389
|
+
if (!contentType || !contentType.startsWith("image/")) {
|
|
2390
|
+
return {
|
|
2391
|
+
content: [
|
|
2392
|
+
{
|
|
2393
|
+
type: "text",
|
|
2394
|
+
text: JSON.stringify({
|
|
2395
|
+
error: "Invalid file type. Wireframes only accept image files (png, jpeg, gif, webp)."
|
|
2396
|
+
})
|
|
2397
|
+
}
|
|
2398
|
+
]
|
|
2399
|
+
};
|
|
2400
|
+
}
|
|
2401
|
+
const { uploadUrl, imageUrl } = await client2.getWireframeUploadUrl({
|
|
2402
|
+
filename,
|
|
2403
|
+
contentType
|
|
2404
|
+
});
|
|
2405
|
+
const wireframe = await client2.createWireframe(roadmapId, { imageUrl });
|
|
2406
|
+
if (description) {
|
|
2407
|
+
await client2.updateWireframe(wireframe.id, { description });
|
|
2408
|
+
}
|
|
2409
|
+
if (outcomeIds && outcomeIds.length > 0) {
|
|
2410
|
+
await client2.updateWireframeOutcomes(wireframe.id, outcomeIds);
|
|
2411
|
+
}
|
|
2412
|
+
const curlCommand = `curl -X PUT -H "Content-Type: ${contentType}" --data-binary @"${filePath}" "${uploadUrl}"`;
|
|
2413
|
+
return {
|
|
2414
|
+
content: [
|
|
2415
|
+
{
|
|
2416
|
+
type: "text",
|
|
2417
|
+
text: JSON.stringify({
|
|
2418
|
+
wireframeId: wireframe.id,
|
|
2419
|
+
imageUrl,
|
|
2420
|
+
curlCommand,
|
|
2421
|
+
instructions: "Execute the curlCommand to upload the file. The wireframe record has been created and will display the image once uploaded."
|
|
2422
|
+
}, null, 2)
|
|
2423
|
+
}
|
|
2424
|
+
]
|
|
2425
|
+
};
|
|
2426
|
+
});
|
|
2427
|
+
}
|
|
2428
|
+
function registerUpdateWireframe(server) {
|
|
2429
|
+
server.registerTool("update_wireframe", {
|
|
2430
|
+
description: "Update a wireframe's description or outcome tags.",
|
|
2431
|
+
inputSchema: {
|
|
2432
|
+
id: z10.string().describe("The UUID of the wireframe"),
|
|
2433
|
+
description: z10.string().nullable().optional().describe("New description for the wireframe"),
|
|
2434
|
+
outcomeIds: z10.array(z10.string()).optional().describe("Array of PRD outcome IDs this wireframe addresses (replaces existing)")
|
|
2435
|
+
}
|
|
2436
|
+
}, async ({
|
|
2437
|
+
id,
|
|
2438
|
+
description,
|
|
2439
|
+
outcomeIds
|
|
2440
|
+
}) => {
|
|
2441
|
+
const client2 = getApiClient();
|
|
2442
|
+
let wireframe;
|
|
2443
|
+
if (description !== undefined) {
|
|
2444
|
+
wireframe = await client2.updateWireframe(id, { description });
|
|
2445
|
+
} else {
|
|
2446
|
+
wireframe = await client2.updateWireframe(id, {});
|
|
2447
|
+
}
|
|
2448
|
+
if (outcomeIds !== undefined) {
|
|
2449
|
+
wireframe = await client2.updateWireframeOutcomes(id, outcomeIds);
|
|
2450
|
+
}
|
|
2451
|
+
return {
|
|
2452
|
+
content: [
|
|
2453
|
+
{
|
|
2454
|
+
type: "text",
|
|
2455
|
+
text: JSON.stringify({
|
|
2456
|
+
id: wireframe.id,
|
|
2457
|
+
imageUrl: wireframe.imageUrl,
|
|
2458
|
+
description: wireframe.description,
|
|
2459
|
+
outcomes: wireframe.outcomes.map((o) => o.prdOutcomeId)
|
|
2460
|
+
}, null, 2)
|
|
2461
|
+
}
|
|
2462
|
+
]
|
|
2463
|
+
};
|
|
2464
|
+
});
|
|
2465
|
+
}
|
|
2466
|
+
function registerDeleteWireframe(server) {
|
|
2467
|
+
server.registerTool("delete_wireframe", {
|
|
2468
|
+
description: "Delete a wireframe (soft delete).",
|
|
2469
|
+
inputSchema: {
|
|
2470
|
+
id: z10.string().describe("The UUID of the wireframe to delete")
|
|
2471
|
+
}
|
|
2472
|
+
}, async ({ id }) => {
|
|
2473
|
+
const client2 = getApiClient();
|
|
2474
|
+
await client2.deleteWireframe(id);
|
|
2475
|
+
return {
|
|
2476
|
+
content: [
|
|
2477
|
+
{
|
|
2478
|
+
type: "text",
|
|
2479
|
+
text: JSON.stringify({ success: true, deleted: id })
|
|
2480
|
+
}
|
|
2481
|
+
]
|
|
2482
|
+
};
|
|
2483
|
+
});
|
|
2484
|
+
}
|
|
2485
|
+
function registerUploadBrainstormMedia(server) {
|
|
2486
|
+
server.registerTool("upload_brainstorm_media", {
|
|
2487
|
+
description: "Upload an image or video to a roadmap item's brainstorming section. Returns a curl command to execute for the upload.",
|
|
2488
|
+
inputSchema: {
|
|
2489
|
+
roadmapId: z10.string().describe("The UUID of the roadmap item"),
|
|
2490
|
+
filePath: z10.string().describe("Absolute path to the image or video file on disk"),
|
|
2491
|
+
description: z10.string().optional().describe("Optional description of the media")
|
|
2492
|
+
}
|
|
2493
|
+
}, async ({
|
|
2494
|
+
roadmapId,
|
|
2495
|
+
filePath,
|
|
2496
|
+
description
|
|
2497
|
+
}) => {
|
|
2498
|
+
const client2 = getApiClient();
|
|
2499
|
+
const filename = filePath.split("/").pop() || "file.bin";
|
|
2500
|
+
const contentType = inferContentType(filename);
|
|
2501
|
+
if (!contentType) {
|
|
2502
|
+
return {
|
|
2503
|
+
content: [
|
|
2504
|
+
{
|
|
2505
|
+
type: "text",
|
|
2506
|
+
text: JSON.stringify({
|
|
2507
|
+
error: "Invalid file type. Brainstorm media accepts images (png, jpeg, gif, webp) and videos (mp4, webm, mov)."
|
|
2508
|
+
})
|
|
2509
|
+
}
|
|
2510
|
+
]
|
|
2511
|
+
};
|
|
2512
|
+
}
|
|
2513
|
+
const mediaType = contentType.startsWith("image/") ? "image" : "video";
|
|
2514
|
+
const { uploadUrl, mediaUrl } = await client2.getBrainstormUploadUrl({
|
|
2515
|
+
filename,
|
|
2516
|
+
contentType
|
|
2517
|
+
});
|
|
2518
|
+
let media = await client2.createBrainstormMedia(roadmapId, { mediaUrl, mediaType });
|
|
2519
|
+
if (description) {
|
|
2520
|
+
media = await client2.updateBrainstormMedia(media.id, { description });
|
|
2521
|
+
}
|
|
2522
|
+
const curlCommand = `curl -X PUT -H "Content-Type: ${contentType}" --data-binary @"${filePath}" "${uploadUrl}"`;
|
|
2523
|
+
return {
|
|
2524
|
+
content: [
|
|
2525
|
+
{
|
|
2526
|
+
type: "text",
|
|
2527
|
+
text: JSON.stringify({
|
|
2528
|
+
mediaId: media.id,
|
|
2529
|
+
mediaUrl,
|
|
2530
|
+
mediaType,
|
|
2531
|
+
curlCommand,
|
|
2532
|
+
instructions: "Execute the curlCommand to upload the file. The media record has been created and will display once uploaded."
|
|
2533
|
+
}, null, 2)
|
|
2534
|
+
}
|
|
2535
|
+
]
|
|
2536
|
+
};
|
|
2537
|
+
});
|
|
2538
|
+
}
|
|
2539
|
+
function registerUpdateBrainstormMedia(server) {
|
|
2540
|
+
server.registerTool("update_brainstorm_media", {
|
|
2541
|
+
description: "Update a brainstorm media item's description.",
|
|
2542
|
+
inputSchema: {
|
|
2543
|
+
id: z10.string().describe("The UUID of the brainstorm media"),
|
|
2544
|
+
description: z10.string().nullable().describe("New description for the media")
|
|
2545
|
+
}
|
|
2546
|
+
}, async ({ id, description }) => {
|
|
2547
|
+
const client2 = getApiClient();
|
|
2548
|
+
const media = await client2.updateBrainstormMedia(id, { description });
|
|
2549
|
+
return {
|
|
2550
|
+
content: [
|
|
2551
|
+
{
|
|
2552
|
+
type: "text",
|
|
2553
|
+
text: JSON.stringify({
|
|
2554
|
+
id: media.id,
|
|
2555
|
+
mediaUrl: media.mediaUrl,
|
|
2556
|
+
mediaType: media.mediaType,
|
|
2557
|
+
description: media.description
|
|
2558
|
+
}, null, 2)
|
|
2559
|
+
}
|
|
2560
|
+
]
|
|
2561
|
+
};
|
|
2562
|
+
});
|
|
2563
|
+
}
|
|
2564
|
+
function registerDeleteBrainstormMedia(server) {
|
|
2565
|
+
server.registerTool("delete_brainstorm_media", {
|
|
2566
|
+
description: "Delete a brainstorm media item (soft delete).",
|
|
2567
|
+
inputSchema: {
|
|
2568
|
+
id: z10.string().describe("The UUID of the brainstorm media to delete")
|
|
2569
|
+
}
|
|
2570
|
+
}, async ({ id }) => {
|
|
2571
|
+
const client2 = getApiClient();
|
|
2572
|
+
await client2.deleteBrainstormMedia(id);
|
|
2573
|
+
return {
|
|
2574
|
+
content: [
|
|
2575
|
+
{
|
|
2576
|
+
type: "text",
|
|
2577
|
+
text: JSON.stringify({ success: true, deleted: id })
|
|
2578
|
+
}
|
|
2579
|
+
]
|
|
2580
|
+
};
|
|
2581
|
+
});
|
|
2582
|
+
}
|
|
2583
|
+
function registerUploadProductDesignMedia(server) {
|
|
2584
|
+
server.registerTool("upload_product_design_media", {
|
|
2585
|
+
description: "Upload an image or video to a product's design media section. Returns a curl command to execute for the upload.",
|
|
2586
|
+
inputSchema: {
|
|
2587
|
+
productId: z10.string().describe("The UUID of the product"),
|
|
2588
|
+
filePath: z10.string().describe("Absolute path to the image or video file on disk"),
|
|
2589
|
+
description: z10.string().optional().describe("Optional description of the media")
|
|
2590
|
+
}
|
|
2591
|
+
}, async ({
|
|
2592
|
+
productId,
|
|
2593
|
+
filePath,
|
|
2594
|
+
description
|
|
2595
|
+
}) => {
|
|
2596
|
+
const client2 = getApiClient();
|
|
2597
|
+
const filename = filePath.split("/").pop() || "file.bin";
|
|
2598
|
+
const contentType = inferContentType(filename);
|
|
2599
|
+
if (!contentType) {
|
|
2600
|
+
return {
|
|
2601
|
+
content: [
|
|
2602
|
+
{
|
|
2603
|
+
type: "text",
|
|
2604
|
+
text: JSON.stringify({
|
|
2605
|
+
error: "Invalid file type. Design media accepts images (png, jpeg, gif, webp) and videos (mp4, webm, mov)."
|
|
2606
|
+
})
|
|
2607
|
+
}
|
|
2608
|
+
]
|
|
2609
|
+
};
|
|
2610
|
+
}
|
|
2611
|
+
const mediaType = contentType.startsWith("image/") ? "image" : "video";
|
|
2612
|
+
const { uploadUrl, mediaUrl } = await client2.getProductDesignUploadUrl(productId, {
|
|
2613
|
+
filename,
|
|
2614
|
+
contentType
|
|
2615
|
+
});
|
|
2616
|
+
let media = await client2.createProductDesignMedia(productId, { mediaUrl, mediaType });
|
|
2617
|
+
if (description) {
|
|
2618
|
+
media = await client2.updateProductDesignMedia(productId, media.id, { description });
|
|
2619
|
+
}
|
|
2620
|
+
const curlCommand = `curl -X PUT -H "Content-Type: ${contentType}" --data-binary @"${filePath}" "${uploadUrl}"`;
|
|
2621
|
+
return {
|
|
2622
|
+
content: [
|
|
2623
|
+
{
|
|
2624
|
+
type: "text",
|
|
2625
|
+
text: JSON.stringify({
|
|
2626
|
+
mediaId: media.id,
|
|
2627
|
+
productId,
|
|
2628
|
+
mediaUrl,
|
|
2629
|
+
mediaType,
|
|
2630
|
+
curlCommand,
|
|
2631
|
+
instructions: "Execute the curlCommand to upload the file. The media record has been created and will display once uploaded."
|
|
2632
|
+
}, null, 2)
|
|
2633
|
+
}
|
|
2634
|
+
]
|
|
2635
|
+
};
|
|
2636
|
+
});
|
|
2637
|
+
}
|
|
2638
|
+
function registerUpdateProductDesignMedia(server) {
|
|
2639
|
+
server.registerTool("update_product_design_media", {
|
|
2640
|
+
description: "Update a product design media item's description.",
|
|
2641
|
+
inputSchema: {
|
|
2642
|
+
productId: z10.string().describe("The UUID of the product"),
|
|
2643
|
+
mediaId: z10.string().describe("The UUID of the design media"),
|
|
2644
|
+
description: z10.string().nullable().describe("New description for the media")
|
|
2645
|
+
}
|
|
2646
|
+
}, async ({
|
|
2647
|
+
productId,
|
|
2648
|
+
mediaId,
|
|
2649
|
+
description
|
|
2650
|
+
}) => {
|
|
2651
|
+
const client2 = getApiClient();
|
|
2652
|
+
const media = await client2.updateProductDesignMedia(productId, mediaId, { description });
|
|
2653
|
+
return {
|
|
2654
|
+
content: [
|
|
2655
|
+
{
|
|
2656
|
+
type: "text",
|
|
2657
|
+
text: JSON.stringify({
|
|
2658
|
+
id: media.id,
|
|
2659
|
+
mediaUrl: media.mediaUrl,
|
|
2660
|
+
mediaType: media.mediaType,
|
|
2661
|
+
description: media.description
|
|
2662
|
+
}, null, 2)
|
|
2663
|
+
}
|
|
2664
|
+
]
|
|
2665
|
+
};
|
|
2666
|
+
});
|
|
2667
|
+
}
|
|
2668
|
+
function registerDeleteProductDesignMedia(server) {
|
|
2669
|
+
server.registerTool("delete_product_design_media", {
|
|
2670
|
+
description: "Delete a product design media item (soft delete).",
|
|
2671
|
+
inputSchema: {
|
|
2672
|
+
productId: z10.string().describe("The UUID of the product"),
|
|
2673
|
+
mediaId: z10.string().describe("The UUID of the design media to delete")
|
|
2674
|
+
}
|
|
2675
|
+
}, async ({ productId, mediaId }) => {
|
|
2676
|
+
const client2 = getApiClient();
|
|
2677
|
+
await client2.deleteProductDesignMedia(productId, mediaId);
|
|
2678
|
+
return {
|
|
2679
|
+
content: [
|
|
2680
|
+
{
|
|
2681
|
+
type: "text",
|
|
2682
|
+
text: JSON.stringify({ success: true, deleted: mediaId })
|
|
2683
|
+
}
|
|
2684
|
+
]
|
|
2685
|
+
};
|
|
2686
|
+
});
|
|
2687
|
+
}
|
|
2262
2688
|
|
|
2263
2689
|
// src/index.ts
|
|
2264
2690
|
async function main() {
|