@cloudinary/asset-management-mcp 0.9.0 → 0.9.2
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/README.md +12 -15
- package/bin/mcp-server.js +269 -379
- package/bin/mcp-server.js.map +17 -17
- package/esm/funcs/searchSearchAssets.d.ts +46 -2
- package/esm/funcs/searchSearchAssets.d.ts.map +1 -1
- package/esm/funcs/searchSearchAssets.js +46 -2
- package/esm/funcs/searchSearchAssets.js.map +1 -1
- package/esm/landing-page.d.ts.map +1 -1
- package/esm/landing-page.js +9 -3
- package/esm/landing-page.js.map +1 -1
- package/esm/lib/config.d.ts +4 -4
- package/esm/lib/config.js +4 -4
- package/esm/mcp-server/apps/app-shared.d.ts +5 -4
- package/esm/mcp-server/apps/app-shared.d.ts.map +1 -1
- package/esm/mcp-server/apps/app-shared.js +79 -12
- package/esm/mcp-server/apps/app-shared.js.map +1 -1
- package/esm/mcp-server/apps/asset-details-app.d.ts.map +1 -1
- package/esm/mcp-server/apps/asset-details-app.js +7 -14
- package/esm/mcp-server/apps/asset-details-app.js.map +1 -1
- package/esm/mcp-server/apps/asset-gallery-app.d.ts.map +1 -1
- package/esm/mcp-server/apps/asset-gallery-app.js +75 -298
- package/esm/mcp-server/apps/asset-gallery-app.js.map +1 -1
- package/esm/mcp-server/apps/asset-upload-app.d.ts.map +1 -1
- package/esm/mcp-server/apps/asset-upload-app.js +29 -24
- package/esm/mcp-server/apps/asset-upload-app.js.map +1 -1
- package/esm/mcp-server/apps/config.d.ts.map +1 -1
- package/esm/mcp-server/apps/config.js +1 -2
- package/esm/mcp-server/apps/config.js.map +1 -1
- package/esm/mcp-server/apps/extensions.d.ts.map +1 -1
- package/esm/mcp-server/apps/extensions.js +6 -1
- package/esm/mcp-server/apps/extensions.js.map +1 -1
- package/esm/mcp-server/cli/serve/impl.js +1 -1
- package/esm/mcp-server/cli/serve/impl.js.map +1 -1
- package/esm/mcp-server/mcp-server.js +1 -1
- package/esm/mcp-server/server.js +1 -1
- package/esm/mcp-server/tools/searchSearchAssets.d.ts.map +1 -1
- package/esm/mcp-server/tools/searchSearchAssets.js +46 -2
- package/esm/mcp-server/tools/searchSearchAssets.js.map +1 -1
- package/esm/models/searchparameters.d.ts +4 -1
- package/esm/models/searchparameters.d.ts.map +1 -1
- package/esm/models/searchparameters.js +9 -8
- package/esm/models/searchparameters.js.map +1 -1
- package/esm/tool-names.js +1 -1
- package/esm/tool-names.js.map +1 -1
- package/esm/types/bigint.d.ts.map +1 -1
- package/esm/types/bigint.js +4 -3
- package/esm/types/bigint.js.map +1 -1
- package/package.json +1 -1
- package/src/funcs/searchSearchAssets.ts +46 -2
- package/src/landing-page.ts +9 -3
- package/src/lib/config.ts +4 -4
- package/src/mcp-server/apps/app-shared.ts +80 -12
- package/src/mcp-server/apps/asset-details-app.ts +7 -13
- package/src/mcp-server/apps/asset-gallery-app.ts +75 -297
- package/src/mcp-server/apps/asset-upload-app.ts +29 -23
- package/src/mcp-server/apps/config.ts +1 -2
- package/src/mcp-server/apps/extensions.ts +6 -1
- package/src/mcp-server/cli/serve/impl.ts +1 -1
- package/src/mcp-server/mcp-server.ts +1 -1
- package/src/mcp-server/server.ts +1 -1
- package/src/mcp-server/tools/searchSearchAssets.ts +46 -2
- package/src/models/searchparameters.ts +25 -9
- package/src/tool-names.ts +1 -1
- package/src/types/bigint.ts +18 -17
package/bin/mcp-server.js
CHANGED
|
@@ -13959,10 +13959,10 @@ var init_config = __esm(() => {
|
|
|
13959
13959
|
]).describe("Regional endpoint selection");
|
|
13960
13960
|
SDK_METADATA = {
|
|
13961
13961
|
language: "typescript",
|
|
13962
|
-
openapiDocVersion: "0.5.
|
|
13963
|
-
sdkVersion: "0.9.
|
|
13964
|
-
genVersion: "2.
|
|
13965
|
-
userAgent: "speakeasy-sdk/mcp-typescript 0.9.
|
|
13962
|
+
openapiDocVersion: "0.5.1",
|
|
13963
|
+
sdkVersion: "0.9.2",
|
|
13964
|
+
genVersion: "2.885.1",
|
|
13965
|
+
userAgent: "speakeasy-sdk/mcp-typescript 0.9.2 2.885.1 0.5.1 @cloudinary/asset-management-mcp"
|
|
13966
13966
|
};
|
|
13967
13967
|
});
|
|
13968
13968
|
|
|
@@ -14021,7 +14021,7 @@ var init_config2 = __esm(() => {
|
|
|
14021
14021
|
"asset-details",
|
|
14022
14022
|
"asset-upload"
|
|
14023
14023
|
];
|
|
14024
|
-
DEFAULT_MCP_APPS = [];
|
|
14024
|
+
DEFAULT_MCP_APPS = [...MCP_APPS];
|
|
14025
14025
|
});
|
|
14026
14026
|
|
|
14027
14027
|
// src/mcp-server/console-logger.ts
|
|
@@ -65624,6 +65624,7 @@ var _infoSchema, _uploadSchema, TOOLTIP_MAP_JSON, SHARED_CSS_TOKENS = `
|
|
|
65624
65624
|
[data-theme="dark"] .status-warn, .dark .status-warn { background: #854d0e; color: #fef08a; }
|
|
65625
65625
|
[data-theme="dark"] .status-err, .dark .status-err { background: #991b1b; color: #fecaca; }
|
|
65626
65626
|
|
|
65627
|
+
html { overflow: hidden; }
|
|
65627
65628
|
body {
|
|
65628
65629
|
font-family: var(--cld-font);
|
|
65629
65630
|
background: var(--cld-bg);
|
|
@@ -65634,16 +65635,35 @@ body {
|
|
|
65634
65635
|
position: relative;
|
|
65635
65636
|
}
|
|
65636
65637
|
.theme-btn {
|
|
65637
|
-
position: absolute; top: 4px; right: 4px; z-index: 900;
|
|
65638
65638
|
width: 22px; height: 22px; border-radius: 50%;
|
|
65639
65639
|
border: 1px solid transparent; background: transparent;
|
|
65640
65640
|
color: var(--cld-text3); cursor: pointer;
|
|
65641
65641
|
display: flex; align-items: center; justify-content: center;
|
|
65642
65642
|
padding: 0; transition: background 0.15s, color 0.15s, border-color 0.15s;
|
|
65643
|
-
opacity: 0.5;
|
|
65643
|
+
opacity: 0.5; flex-shrink: 0;
|
|
65644
65644
|
}
|
|
65645
65645
|
.theme-btn:hover { background: var(--cld-bg3); color: var(--cld-text); border-color: var(--cld-border); opacity: 1; }
|
|
65646
65646
|
.theme-btn svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
|
|
65647
|
+
/* Shared icon-button — square pill, same family as theme-btn */
|
|
65648
|
+
.icon-btn {
|
|
65649
|
+
display: inline-flex; align-items: center; justify-content: center; gap: 5px;
|
|
65650
|
+
background: none; border: 1px solid var(--cld-border); border-radius: var(--cld-radius-sm);
|
|
65651
|
+
color: var(--cld-text2); cursor: pointer; padding: 4px 8px;
|
|
65652
|
+
font-size: 12px; font-weight: 500; font-family: inherit; line-height: 1;
|
|
65653
|
+
transition: background 0.15s, color 0.15s, border-color 0.15s;
|
|
65654
|
+
white-space: nowrap; flex-shrink: 0;
|
|
65655
|
+
}
|
|
65656
|
+
.icon-btn:hover { background: var(--cld-bg3); color: var(--cld-text); border-color: var(--cld-border2); }
|
|
65657
|
+
.icon-btn svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }
|
|
65658
|
+
/* icon-only variant (no text label) */
|
|
65659
|
+
.icon-btn.icon-only { padding: 4px; width: 28px; height: 28px; }
|
|
65660
|
+
/* header state icon (decorative, not a button) */
|
|
65661
|
+
.upload-header-icon { display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
|
|
65662
|
+
.upload-header-icon svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
|
|
65663
|
+
.upload-header-icon.icon-success { color: var(--cld-success); }
|
|
65664
|
+
.upload-header-icon.icon-error { color: var(--cld-error); }
|
|
65665
|
+
.upload-header-icon.icon-warning { color: var(--cld-warning); }
|
|
65666
|
+
.upload-header-icon.icon-accent { color: var(--cld-accent); }
|
|
65647
65667
|
`, SHARED_CSS_COMPONENTS = `
|
|
65648
65668
|
.link { cursor: pointer; }
|
|
65649
65669
|
.link:hover { color: var(--cld-accent); text-decoration: underline; }
|
|
@@ -65894,7 +65914,8 @@ details.detail-section > summary.detail-section-title::-webkit-details-marker {
|
|
|
65894
65914
|
}
|
|
65895
65915
|
.upload-zone:hover { border-color: var(--cld-accent); background: var(--cld-accent-bg); }
|
|
65896
65916
|
.upload-zone.dragover { border-color: var(--cld-accent); background: var(--cld-accent-bg); }
|
|
65897
|
-
.upload-zone-icon {
|
|
65917
|
+
.upload-zone-icon { margin-bottom: 8px; color: var(--cld-text3); display: flex; align-items: center; justify-content: center; }
|
|
65918
|
+
.upload-zone-icon svg { width: 36px; height: 36px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
|
|
65898
65919
|
.upload-zone-text { font-size: 14px; color: var(--cld-text2); margin-bottom: 4px; }
|
|
65899
65920
|
.upload-zone-hint { font-size: 12px; color: var(--cld-text3); }
|
|
65900
65921
|
.upload-zone-btn {
|
|
@@ -65940,8 +65961,9 @@ details.detail-section > summary.detail-section-title::-webkit-details-marker {
|
|
|
65940
65961
|
.upload-preview-icon {
|
|
65941
65962
|
width: 56px; height: 56px; border-radius: var(--cld-radius-sm);
|
|
65942
65963
|
background: var(--cld-bg3); flex-shrink: 0; display: flex;
|
|
65943
|
-
align-items: center; justify-content: center;
|
|
65964
|
+
align-items: center; justify-content: center; color: var(--cld-text3);
|
|
65944
65965
|
}
|
|
65966
|
+
.upload-preview-icon svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
|
|
65945
65967
|
.upload-preview-info { flex: 1; min-width: 0; }
|
|
65946
65968
|
.upload-preview-name { font-size: 13px; font-weight: 600; color: var(--cld-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
65947
65969
|
.upload-preview-meta { font-size: 11px; color: var(--cld-text3); margin-top: 2px; }
|
|
@@ -66090,19 +66112,15 @@ details.upload-section > .upload-form { margin: 0; padding: 10px 12px; }
|
|
|
66090
66112
|
background: var(--cld-accent-bg); border: 1px solid var(--cld-accent);
|
|
66091
66113
|
border-radius: var(--cld-radius); margin-bottom: 4px; position: relative;
|
|
66092
66114
|
}
|
|
66093
|
-
.upload-staged-icon {
|
|
66115
|
+
.upload-staged-icon { flex-shrink: 0; display: flex; align-items: center; color: var(--cld-accent); }
|
|
66116
|
+
.upload-staged-icon svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
|
|
66094
66117
|
.upload-staged-info { flex: 1; min-width: 0; }
|
|
66095
66118
|
.upload-staged-name {
|
|
66096
66119
|
font-size: 13px; font-weight: 600; color: var(--cld-text);
|
|
66097
66120
|
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
66098
66121
|
}
|
|
66099
66122
|
.upload-staged-meta { font-size: 11px; color: var(--cld-text3); margin-top: 2px; }
|
|
66100
|
-
.upload-staged-clear {
|
|
66101
|
-
background: none; border: none; cursor: pointer; font-size: 16px;
|
|
66102
|
-
color: var(--cld-text3); padding: 4px 6px; border-radius: var(--cld-radius-sm);
|
|
66103
|
-
transition: color 0.15s, background 0.15s; flex-shrink: 0;
|
|
66104
|
-
}
|
|
66105
|
-
.upload-staged-clear:hover { color: var(--cld-error); background: rgba(206,25,13,0.08); }
|
|
66123
|
+
.upload-staged-clear:hover { color: var(--cld-error); border-color: var(--cld-error); background: rgba(206,25,13,0.08); }
|
|
66106
66124
|
|
|
66107
66125
|
/* Upload submit button */
|
|
66108
66126
|
.upload-submit {
|
|
@@ -66148,6 +66166,21 @@ details.upload-section > .upload-form { margin: 0; padding: 10px 12px; }
|
|
|
66148
66166
|
.json-bool { color: #a9e34b; }
|
|
66149
66167
|
.json-null { color: #868e96; }
|
|
66150
66168
|
}
|
|
66169
|
+
`, SHARED_JS_ICONS = `
|
|
66170
|
+
var IC = {
|
|
66171
|
+
refresh: '<svg viewBox="0 0 24 24"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M3 21v-5h5"/></svg>',
|
|
66172
|
+
chevronLeft:'<svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>',
|
|
66173
|
+
arrowDown: '<svg viewBox="0 0 24 24"><line x1="12" y1="5" x2="12" y2="19"/><polyline points="19 12 12 19 5 12"/></svg>',
|
|
66174
|
+
x: '<svg viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',
|
|
66175
|
+
zap: '<svg viewBox="0 0 24 24"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>',
|
|
66176
|
+
uploadCloud:'<svg viewBox="0 0 24 24"><polyline points="16 16 12 12 8 16"/><line x1="12" y1="12" x2="12" y2="21"/><path d="M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3"/></svg>',
|
|
66177
|
+
alertTriangle:'<svg viewBox="0 0 24 24"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>',
|
|
66178
|
+
folderOpen: '<svg viewBox="0 0 24 24"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/><polyline points="22 13 17 13 15 16 9 16 7 13 2 13"/></svg>',
|
|
66179
|
+
checkCircle:'<svg viewBox="0 0 24 24"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>',
|
|
66180
|
+
clock: '<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>',
|
|
66181
|
+
file: '<svg viewBox="0 0 24 24"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"/><polyline points="13 2 13 9 20 9"/></svg>',
|
|
66182
|
+
image: '<svg viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>',
|
|
66183
|
+
};
|
|
66151
66184
|
`, SHARED_JS_MCP_CLIENT = `
|
|
66152
66185
|
var RPC_TIMEOUT_MS = 15000;
|
|
66153
66186
|
var TOOL_CALL_TIMEOUT_MS = 30000;
|
|
@@ -66233,6 +66266,29 @@ class MCPApp {
|
|
|
66233
66266
|
}
|
|
66234
66267
|
}
|
|
66235
66268
|
`, SHARED_JS_HELPERS = `
|
|
66269
|
+
function copyText(text) {
|
|
66270
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
66271
|
+
return navigator.clipboard.writeText(text).catch(function() { return _copyFallback(text); });
|
|
66272
|
+
}
|
|
66273
|
+
return _copyFallback(text);
|
|
66274
|
+
}
|
|
66275
|
+
function _copyFallback(text) {
|
|
66276
|
+
return new Promise(function(resolve, reject) {
|
|
66277
|
+
try {
|
|
66278
|
+
var ta = document.createElement("textarea");
|
|
66279
|
+
ta.value = text;
|
|
66280
|
+
ta.setAttribute("readonly", "");
|
|
66281
|
+
ta.style.position = "fixed"; ta.style.top = "0"; ta.style.left = "0";
|
|
66282
|
+
ta.style.opacity = "0"; ta.style.pointerEvents = "none";
|
|
66283
|
+
document.body.appendChild(ta);
|
|
66284
|
+
ta.select(); ta.setSelectionRange(0, text.length);
|
|
66285
|
+
var ok = document.execCommand("copy");
|
|
66286
|
+
document.body.removeChild(ta);
|
|
66287
|
+
if (ok) resolve(); else reject(new Error("Clipboard unavailable"));
|
|
66288
|
+
} catch (e) { reject(e); }
|
|
66289
|
+
});
|
|
66290
|
+
}
|
|
66291
|
+
|
|
66236
66292
|
function fmtBytes(b) {
|
|
66237
66293
|
if (!b) return "";
|
|
66238
66294
|
var u = ["B","KB","MB","GB"], i = Math.min(Math.floor(Math.log(b)/Math.log(1024)), 3);
|
|
@@ -67456,7 +67512,16 @@ function renderThemeToggle() {
|
|
|
67456
67512
|
applyTheme();
|
|
67457
67513
|
renderThemeToggle();
|
|
67458
67514
|
});
|
|
67459
|
-
document.
|
|
67515
|
+
var slot = document.getElementById("header-actions");
|
|
67516
|
+
if (slot) {
|
|
67517
|
+
slot.appendChild(btn);
|
|
67518
|
+
} else {
|
|
67519
|
+
btn.style.position = "absolute";
|
|
67520
|
+
btn.style.top = "4px";
|
|
67521
|
+
btn.style.right = "4px";
|
|
67522
|
+
btn.style.zIndex = "900";
|
|
67523
|
+
document.body.appendChild(btn);
|
|
67524
|
+
}
|
|
67460
67525
|
}
|
|
67461
67526
|
|
|
67462
67527
|
function setupHostContext(app) {
|
|
@@ -67550,90 +67615,10 @@ var GALLERY_CSS = `
|
|
|
67550
67615
|
font-size: var(--cld-font-xxs); color: var(--cld-text3); background: var(--cld-bg3);
|
|
67551
67616
|
padding: 2px 8px; border-radius: 20px; font-weight: 500;
|
|
67552
67617
|
}
|
|
67553
|
-
|
|
67554
|
-
|
|
67555
|
-
|
|
67556
|
-
|
|
67557
|
-
transition: color 0.15s, border-color 0.15s;
|
|
67558
|
-
}
|
|
67559
|
-
.select-all-btn:hover { color: var(--cld-accent); border-color: var(--cld-accent); }
|
|
67560
|
-
.refresh-btn {
|
|
67561
|
-
background: none; border: 1px solid var(--cld-border); border-radius: var(--cld-radius-sm);
|
|
67562
|
-
color: var(--cld-text2); cursor: pointer; font-size: 14px; padding: 2px 7px;
|
|
67563
|
-
line-height: 1; transition: background 0.15s, color 0.15s;
|
|
67564
|
-
}
|
|
67565
|
-
.refresh-btn:hover { background: var(--cld-bg3); color: var(--cld-text); }
|
|
67566
|
-
|
|
67567
|
-
/* ── Filter bar ── */
|
|
67568
|
-
.filter-row {
|
|
67569
|
-
margin-bottom: var(--cld-sp-md); display: flex; gap: 8px; align-items: center;
|
|
67570
|
-
}
|
|
67571
|
-
.filter-text-wrap { position: relative; flex: 1; }
|
|
67572
|
-
.filter-input {
|
|
67573
|
-
width: 100%; height: 36px; padding: 0 12px 0 34px;
|
|
67574
|
-
border: 1px solid var(--cld-border); border-radius: var(--cld-radius);
|
|
67575
|
-
background: var(--cld-bg); font-size: 12.5px; color: var(--cld-text);
|
|
67576
|
-
outline: none; font-family: inherit;
|
|
67577
|
-
transition: border-color 0.18s, box-shadow 0.18s;
|
|
67578
|
-
}
|
|
67579
|
-
.filter-input::placeholder { color: var(--cld-text3); }
|
|
67580
|
-
.filter-input:focus {
|
|
67581
|
-
border-color: var(--cld-accent);
|
|
67582
|
-
box-shadow: 0 0 0 3px rgba(52,72,197,0.1);
|
|
67583
|
-
}
|
|
67584
|
-
[data-theme="dark"] .filter-input:focus { box-shadow: 0 0 0 3px rgba(13,154,255,0.15); }
|
|
67585
|
-
.filter-icon {
|
|
67586
|
-
position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
|
|
67587
|
-
color: var(--cld-text3); pointer-events: none; display: flex; align-items: center;
|
|
67588
|
-
}
|
|
67589
|
-
.filter-clear {
|
|
67590
|
-
position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
|
|
67591
|
-
background: none; border: none; color: var(--cld-text3); cursor: pointer;
|
|
67592
|
-
font-size: 14px; line-height: 1; padding: 2px 4px; border-radius: 4px;
|
|
67593
|
-
display: none; font-family: inherit;
|
|
67594
|
-
}
|
|
67595
|
-
.filter-clear:hover { color: var(--cld-text); background: var(--cld-border); }
|
|
67596
|
-
.filter-clear.visible { display: block; }
|
|
67597
|
-
|
|
67598
|
-
/* Aspect-ratio dropdown */
|
|
67599
|
-
.aspect-dropdown { position: relative; flex-shrink: 0; user-select: none; }
|
|
67600
|
-
.aspect-btn {
|
|
67601
|
-
height: 36px; padding: 0 10px; border: 1px solid var(--cld-border);
|
|
67602
|
-
border-radius: var(--cld-radius); background: var(--cld-bg);
|
|
67603
|
-
font-size: 12.5px; color: var(--cld-text); cursor: pointer;
|
|
67604
|
-
display: flex; align-items: center; gap: 6px; white-space: nowrap;
|
|
67605
|
-
transition: border-color 0.18s, box-shadow 0.18s, background 0.18s;
|
|
67606
|
-
font-family: inherit; outline: none;
|
|
67607
|
-
}
|
|
67608
|
-
.aspect-btn:hover { border-color: var(--cld-border2); }
|
|
67609
|
-
.aspect-btn.active {
|
|
67610
|
-
border-color: var(--cld-accent); background: var(--cld-accent-bg);
|
|
67611
|
-
color: var(--cld-accent); font-weight: 600;
|
|
67612
|
-
}
|
|
67613
|
-
.aspect-btn-chevron { color: var(--cld-text3); flex-shrink: 0; transition: transform 0.18s; }
|
|
67614
|
-
.aspect-btn.open .aspect-btn-chevron { transform: rotate(180deg); }
|
|
67615
|
-
.aspect-menu {
|
|
67616
|
-
position: absolute; top: calc(100% + 6px); right: 0;
|
|
67617
|
-
background: var(--cld-bg); border: 1px solid var(--cld-border);
|
|
67618
|
-
border-radius: 10px; box-shadow: var(--cld-shadow-md);
|
|
67619
|
-
padding: 4px; min-width: 160px; z-index: 50; display: none;
|
|
67620
|
-
}
|
|
67621
|
-
.aspect-menu.open { display: block; }
|
|
67622
|
-
.aspect-option {
|
|
67623
|
-
display: flex; align-items: center; gap: 10px;
|
|
67624
|
-
padding: 7px 10px; border-radius: 6px; font-size: 12.5px;
|
|
67625
|
-
color: var(--cld-text); cursor: pointer; transition: background 0.18s;
|
|
67626
|
-
}
|
|
67627
|
-
.aspect-option:hover { background: var(--cld-bg3); }
|
|
67628
|
-
.aspect-option.selected { color: var(--cld-accent); font-weight: 600; }
|
|
67629
|
-
.aspect-opt-icon { color: var(--cld-text3); display: flex; align-items: center; flex-shrink: 0; }
|
|
67630
|
-
.aspect-option.selected .aspect-opt-icon { color: var(--cld-accent); }
|
|
67631
|
-
.aspect-check { margin-left: auto; color: var(--cld-accent); opacity: 0; }
|
|
67632
|
-
.aspect-option.selected .aspect-check { opacity: 1; }
|
|
67633
|
-
.no-results {
|
|
67634
|
-
grid-column: 1 / -1; padding: 60px 20px;
|
|
67635
|
-
text-align: center; color: var(--cld-text3); font-size: 13px;
|
|
67636
|
-
}
|
|
67618
|
+
/* action-btn svg sizing */
|
|
67619
|
+
.action-btn svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }
|
|
67620
|
+
/* select bar svg */
|
|
67621
|
+
.bar-btn svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }
|
|
67637
67622
|
|
|
67638
67623
|
/* ── Grid ── */
|
|
67639
67624
|
.grid {
|
|
@@ -67692,18 +67677,11 @@ var GALLERY_CSS = `
|
|
|
67692
67677
|
opacity: 0; transition: opacity 0.18s; z-index: 4; pointer-events: none;
|
|
67693
67678
|
}
|
|
67694
67679
|
.card:hover .tags-overlay { opacity: 1; }
|
|
67695
|
-
.grid.filtering .tags-overlay { opacity: 1; }
|
|
67696
67680
|
.tag-overlay {
|
|
67697
67681
|
font-size: 10px; color: white;
|
|
67698
67682
|
background: rgba(10, 12, 18, 0.55); padding: 2px 7px; border-radius: 20px;
|
|
67699
67683
|
backdrop-filter: blur(6px); font-weight: 600; letter-spacing: 0.02em;
|
|
67700
67684
|
}
|
|
67701
|
-
.tag-overlay.tag-match { background: rgba(52, 72, 197, 0.82); }
|
|
67702
|
-
.tag-overlay mark {
|
|
67703
|
-
background: rgba(255, 213, 79, 0.5); color: white;
|
|
67704
|
-
border-radius: 2px; padding: 0 1px;
|
|
67705
|
-
}
|
|
67706
|
-
|
|
67707
67685
|
/* Floating action buttons */
|
|
67708
67686
|
.card-actions {
|
|
67709
67687
|
position: absolute; bottom: 10px; left: 0; right: 0;
|
|
@@ -67778,7 +67756,6 @@ var GALLERY_CSS = `
|
|
|
67778
67756
|
opacity: 0; pointer-events: none; z-index: 100; white-space: nowrap;
|
|
67779
67757
|
}
|
|
67780
67758
|
.select-bar.visible { transform: translateX(-50%) translateY(0); opacity: 1; pointer-events: all; }
|
|
67781
|
-
.select-bar-spacer { height: 72px; }
|
|
67782
67759
|
.select-count { font-size: 13px; font-weight: 600; margin-right: 8px; }
|
|
67783
67760
|
.bar-btn {
|
|
67784
67761
|
height: 36px; padding: 0 14px; border: none; border-radius: 30px;
|
|
@@ -67817,8 +67794,6 @@ var pendingCall = {
|
|
|
67817
67794
|
args: null,
|
|
67818
67795
|
};
|
|
67819
67796
|
var selected = new Set();
|
|
67820
|
-
var filterQuery = "";
|
|
67821
|
-
var aspectFilter = "";
|
|
67822
67797
|
var app = new MCPApp({ name: "Cloudinary Asset Gallery", version: "1.0.0" });
|
|
67823
67798
|
setupHostContext(app);
|
|
67824
67799
|
|
|
@@ -67842,24 +67817,6 @@ function showToast(msg) {
|
|
|
67842
67817
|
_toastTimer = setTimeout(function() { t.classList.remove("show"); }, 2000);
|
|
67843
67818
|
}
|
|
67844
67819
|
|
|
67845
|
-
function getAspect(r) {
|
|
67846
|
-
if (!r.width || !r.height) return "";
|
|
67847
|
-
var ratio = r.width / r.height;
|
|
67848
|
-
if (ratio > 1.1) return "landscape";
|
|
67849
|
-
if (ratio < 0.9) return "portrait";
|
|
67850
|
-
return "square";
|
|
67851
|
-
}
|
|
67852
|
-
|
|
67853
|
-
function highlightText(text, query) {
|
|
67854
|
-
if (!query) return esc(text);
|
|
67855
|
-
var lo = text.toLowerCase();
|
|
67856
|
-
var idx = lo.indexOf(query);
|
|
67857
|
-
if (idx === -1) return esc(text);
|
|
67858
|
-
return esc(text.slice(0, idx))
|
|
67859
|
-
+ "<mark>" + esc(text.slice(idx, idx + query.length)) + "</mark>"
|
|
67860
|
-
+ esc(text.slice(idx + query.length));
|
|
67861
|
-
}
|
|
67862
|
-
|
|
67863
67820
|
function updateSelectBar() {
|
|
67864
67821
|
var bar = document.getElementById("select-bar");
|
|
67865
67822
|
var countEl = document.getElementById("select-count");
|
|
@@ -67867,8 +67824,6 @@ function updateSelectBar() {
|
|
|
67867
67824
|
var n = selected.size;
|
|
67868
67825
|
countEl.textContent = n + " selected";
|
|
67869
67826
|
bar.classList.toggle("visible", n > 0);
|
|
67870
|
-
var spacer = document.getElementById("select-bar-spacer");
|
|
67871
|
-
if (spacer) spacer.style.display = n > 0 ? "" : "none";
|
|
67872
67827
|
var btn = document.getElementById("select-all-btn");
|
|
67873
67828
|
if (btn) {
|
|
67874
67829
|
var visible = getVisibleIndices();
|
|
@@ -67935,11 +67890,9 @@ function copyAssetUrl(type, idx) {
|
|
|
67935
67890
|
var url = r.secure_url || r.url || "";
|
|
67936
67891
|
var copyUrl = type === "optimized" ? optimizedUrl(url, r) : url;
|
|
67937
67892
|
if (!copyUrl) return;
|
|
67938
|
-
|
|
67939
|
-
|
|
67940
|
-
|
|
67941
|
-
});
|
|
67942
|
-
} catch(e) { showError("Copy Failed", String(e)); }
|
|
67893
|
+
copyText(copyUrl).then(function() {
|
|
67894
|
+
showToast(type === "optimized" ? "\\u2728 Optimized URL copied" : "URL copied");
|
|
67895
|
+
}).catch(function(e) { showError("Copy Failed", e && e.message ? e.message : String(e)); });
|
|
67943
67896
|
}
|
|
67944
67897
|
|
|
67945
67898
|
function downloadOne(idx) {
|
|
@@ -67961,134 +67914,74 @@ function copySelectedUrls(type) {
|
|
|
67961
67914
|
urls.push(type === "optimized" ? optimizedUrl(url, r) : url);
|
|
67962
67915
|
});
|
|
67963
67916
|
if (!urls.length) return;
|
|
67964
|
-
|
|
67965
|
-
|
|
67966
|
-
|
|
67967
|
-
});
|
|
67968
|
-
} catch(e) { showError("Copy Failed", String(e)); }
|
|
67917
|
+
copyText(urls.join("\\n")).then(function() {
|
|
67918
|
+
showToast(urls.length + " " + (type === "optimized" ? "optimized " : "") + "URLs copied");
|
|
67919
|
+
}).catch(function(e) { showError("Copy Failed", e && e.message ? e.message : String(e)); });
|
|
67969
67920
|
}
|
|
67970
67921
|
|
|
67971
|
-
function downloadSelected() {
|
|
67972
|
-
|
|
67922
|
+
async function downloadSelected() {
|
|
67923
|
+
if (selected.size === 0) return;
|
|
67924
|
+
|
|
67925
|
+
var picks = [];
|
|
67973
67926
|
selected.forEach(function(i) {
|
|
67974
67927
|
var r = allResources[i];
|
|
67975
|
-
if (
|
|
67976
|
-
var url = r.secure_url || r.url || "";
|
|
67977
|
-
var dl = downloadUrl(url, r);
|
|
67978
|
-
if (dl) { app._rpc("ui/open-link", { url: dl }); count++; }
|
|
67928
|
+
if (r && r.public_id) picks.push(r);
|
|
67979
67929
|
});
|
|
67980
|
-
if (
|
|
67981
|
-
}
|
|
67982
|
-
|
|
67983
|
-
function handleFilter() {
|
|
67984
|
-
var input = document.getElementById("filter-input");
|
|
67985
|
-
filterQuery = input ? input.value.trim().toLowerCase() : "";
|
|
67930
|
+
if (!picks.length) return;
|
|
67986
67931
|
|
|
67987
|
-
var
|
|
67988
|
-
|
|
67932
|
+
var requestBody = {
|
|
67933
|
+
mode: "create",
|
|
67934
|
+
target_format: "zip",
|
|
67935
|
+
keep_derived: true,
|
|
67936
|
+
target_public_id: "mcp-gallery-archive-" + Date.now(),
|
|
67937
|
+
fully_qualified_public_ids: picks.map(function(r) {
|
|
67938
|
+
return (r.resource_type || "image") + "/" + (r.type || "upload") + "/" + r.public_id;
|
|
67939
|
+
}),
|
|
67940
|
+
};
|
|
67989
67941
|
|
|
67990
|
-
var
|
|
67991
|
-
|
|
67942
|
+
var btn = document.getElementById("bar-download");
|
|
67943
|
+
var origLabel = btn ? btn.innerHTML : "";
|
|
67944
|
+
if (btn) { btn.innerHTML = "Creating archive\\u2026"; btn.disabled = true; }
|
|
67992
67945
|
|
|
67993
|
-
|
|
67994
|
-
|
|
67995
|
-
|
|
67946
|
+
try {
|
|
67947
|
+
var res = await app.callServerTool({
|
|
67948
|
+
name: "generate-archive",
|
|
67949
|
+
arguments: {
|
|
67950
|
+
resource_type: "all",
|
|
67951
|
+
RequestBody: requestBody,
|
|
67952
|
+
},
|
|
67953
|
+
});
|
|
67996
67954
|
|
|
67997
|
-
|
|
67998
|
-
|
|
67999
|
-
|
|
68000
|
-
|
|
68001
|
-
|
|
67955
|
+
var data = ingestResult(res);
|
|
67956
|
+
if (data && (data._error || data._parseError)) {
|
|
67957
|
+
showError("Archive Failed", unwrapApiError(data._message));
|
|
67958
|
+
return;
|
|
67959
|
+
}
|
|
67960
|
+
var archiveUrl = data && (data.secure_url || data.url);
|
|
67961
|
+
if (!archiveUrl) {
|
|
67962
|
+
showError("Archive Failed", "No delivery URL returned.");
|
|
67963
|
+
return;
|
|
67964
|
+
}
|
|
67965
|
+
try { await copyText(archiveUrl); } catch (e) { /* ignore */ }
|
|
67966
|
+
app._rpc("ui/open-link", { url: archiveUrl });
|
|
67967
|
+
showToast("Archive saved as raw in Cloudinary \\u2014 opening URL (" + picks.length + " asset" + (picks.length > 1 ? "s" : "") + ")");
|
|
67968
|
+
} catch (e) {
|
|
67969
|
+
showError("Archive Failed", unwrapApiError(e && e.message ? e.message : String(e)));
|
|
67970
|
+
} finally {
|
|
67971
|
+
if (btn) { btn.innerHTML = origLabel; btn.disabled = false; }
|
|
67972
|
+
}
|
|
67973
|
+
}
|
|
68002
67974
|
|
|
68003
|
-
|
|
68004
|
-
|
|
68005
|
-
|
|
68006
|
-
|
|
68007
|
-
|
|
68008
|
-
|
|
68009
|
-
|
|
68010
|
-
|
|
68011
|
-
|
|
68012
|
-
|
|
68013
|
-
var tagsEl = document.getElementById("tags-overlay-" + i);
|
|
68014
|
-
if (tagsEl && tags.length) {
|
|
68015
|
-
var maxOv = 3;
|
|
68016
|
-
var matchedTags = [];
|
|
68017
|
-
var otherTags = [];
|
|
68018
|
-
for (var ti = 0; ti < tags.length; ti++) {
|
|
68019
|
-
var isMatch = filterQuery && tags[ti].toLowerCase().indexOf(filterQuery) !== -1;
|
|
68020
|
-
if (isMatch) matchedTags.push(tags[ti]);
|
|
68021
|
-
else otherTags.push(tags[ti]);
|
|
68022
|
-
}
|
|
68023
|
-
var shown = matchedTags.slice();
|
|
68024
|
-
var remaining = maxOv - shown.length;
|
|
68025
|
-
if (remaining > 0) shown = shown.concat(otherTags.slice(0, remaining));
|
|
68026
|
-
var hidden = tags.length - shown.length;
|
|
68027
|
-
var hiddenTags = tags.filter(function(t) { return shown.indexOf(t) === -1; });
|
|
68028
|
-
tagsEl.innerHTML = shown.map(function(t) {
|
|
68029
|
-
var matched = filterQuery && t.toLowerCase().indexOf(filterQuery) !== -1;
|
|
68030
|
-
return '<span class="tag-overlay' + (matched ? ' tag-match' : '') + '">' + highlightText(t, filterQuery) + '</span>';
|
|
68031
|
-
}).join("") + (hidden > 0 ? '<span class="tag-overlay" title="' + esc(hiddenTags.join(", ")) + '">+' + hidden + '</span>' : '');
|
|
68032
|
-
}
|
|
68033
|
-
|
|
68034
|
-
if (match) visibleCount++;
|
|
68035
|
-
}
|
|
68036
|
-
|
|
68037
|
-
var badge = document.getElementById("count-badge");
|
|
68038
|
-
if (badge) {
|
|
68039
|
-
badge.textContent = anyFilter
|
|
68040
|
-
? visibleCount + " of " + allResources.length
|
|
68041
|
-
: allResources.length + (lastCursor ? "+" : "") + " items";
|
|
68042
|
-
}
|
|
68043
|
-
|
|
68044
|
-
var noRes = document.getElementById("no-results");
|
|
68045
|
-
if (visibleCount === 0 && anyFilter) {
|
|
68046
|
-
if (!noRes && grid) {
|
|
68047
|
-
noRes = document.createElement("div");
|
|
68048
|
-
noRes.id = "no-results";
|
|
68049
|
-
noRes.className = "no-results";
|
|
68050
|
-
grid.appendChild(noRes);
|
|
68051
|
-
}
|
|
68052
|
-
if (noRes) noRes.textContent = "No results" + (filterQuery ? ' for "' + filterQuery + '"' : "") + (aspectFilter ? " in " + aspectFilter + " images" : "");
|
|
68053
|
-
} else if (noRes) {
|
|
68054
|
-
noRes.remove();
|
|
68055
|
-
}
|
|
68056
|
-
}
|
|
68057
|
-
|
|
68058
|
-
function clearFilter() {
|
|
68059
|
-
var input = document.getElementById("filter-input");
|
|
68060
|
-
if (input) input.value = "";
|
|
68061
|
-
aspectFilter = "";
|
|
68062
|
-
var label = document.getElementById("aspect-btn-label");
|
|
68063
|
-
if (label) label.textContent = "All orientations";
|
|
68064
|
-
document.querySelectorAll(".aspect-option").forEach(function(o) {
|
|
68065
|
-
o.classList.toggle("selected", o.getAttribute("data-value") === "");
|
|
68066
|
-
});
|
|
68067
|
-
handleFilter();
|
|
68068
|
-
}
|
|
68069
|
-
|
|
68070
|
-
function toggleAspectMenu(e) {
|
|
68071
|
-
e.stopPropagation();
|
|
68072
|
-
var btn = document.getElementById("aspect-btn");
|
|
68073
|
-
var menu = document.getElementById("aspect-menu");
|
|
68074
|
-
if (!btn || !menu) return;
|
|
68075
|
-
var open = menu.classList.toggle("open");
|
|
68076
|
-
btn.classList.toggle("open", open);
|
|
68077
|
-
}
|
|
68078
|
-
|
|
68079
|
-
function selectAspect(val) {
|
|
68080
|
-
aspectFilter = val;
|
|
68081
|
-
var labels = { "": "All orientations", landscape: "Landscape", portrait: "Portrait", square: "Square" };
|
|
68082
|
-
var label = document.getElementById("aspect-btn-label");
|
|
68083
|
-
if (label) label.textContent = labels[aspectFilter] || "All orientations";
|
|
68084
|
-
document.querySelectorAll(".aspect-option").forEach(function(o) {
|
|
68085
|
-
o.classList.toggle("selected", o.getAttribute("data-value") === aspectFilter);
|
|
68086
|
-
});
|
|
68087
|
-
var menu = document.getElementById("aspect-menu");
|
|
68088
|
-
var btn = document.getElementById("aspect-btn");
|
|
68089
|
-
if (menu) menu.classList.remove("open");
|
|
68090
|
-
if (btn) btn.classList.remove("open");
|
|
68091
|
-
handleFilter();
|
|
67975
|
+
function unwrapApiError(raw) {
|
|
67976
|
+
if (!raw) return "Unknown error.";
|
|
67977
|
+
var msg = String(raw);
|
|
67978
|
+
try {
|
|
67979
|
+
if (msg.charAt(0) === "{") {
|
|
67980
|
+
var parsed = JSON.parse(msg);
|
|
67981
|
+
msg = (parsed && parsed.error && parsed.error.message) || msg;
|
|
67982
|
+
}
|
|
67983
|
+
} catch (e) { /* keep raw */ }
|
|
67984
|
+
return msg;
|
|
68092
67985
|
}
|
|
68093
67986
|
|
|
68094
67987
|
function render() {
|
|
@@ -68108,41 +68001,12 @@ function render() {
|
|
|
68108
68001
|
h += '<h1>Results</h1>';
|
|
68109
68002
|
h += '<span class="count-badge" id="count-badge">' + allResources.length + (lastCursor ? "+" : "") + ' items</span>';
|
|
68110
68003
|
h += '</div>';
|
|
68111
|
-
h += '<div style="display:flex;align-items:center;gap:8px">';
|
|
68112
|
-
h += '<button class="
|
|
68113
|
-
h += '<button class="
|
|
68004
|
+
h += '<div id="header-actions" style="display:flex;align-items:center;gap:8px">';
|
|
68005
|
+
h += '<button class="icon-btn" id="select-all-btn">Select all</button>';
|
|
68006
|
+
h += '<button class="icon-btn icon-only" id="refresh-gallery" title="Refresh">' + IC.refresh + '</button>';
|
|
68114
68007
|
h += '</div>';
|
|
68115
68008
|
h += '</div>';
|
|
68116
68009
|
|
|
68117
|
-
// Filter bar
|
|
68118
|
-
h += '<div class="filter-row">';
|
|
68119
|
-
h += '<div class="filter-text-wrap">';
|
|
68120
|
-
h += '<span class="filter-icon"><svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="6.5" cy="6.5" r="4.5"/><path d="M10.5 10.5l3 3"/></svg></span>';
|
|
68121
|
-
h += '<input class="filter-input" id="filter-input" type="text" placeholder="Filter by filename or tag\\u2026" autocomplete="off" spellcheck="false">';
|
|
68122
|
-
h += '<button class="filter-clear" id="filter-clear">\\u2715</button>';
|
|
68123
|
-
h += '</div>';
|
|
68124
|
-
h += '<div class="aspect-dropdown" id="aspect-dropdown">';
|
|
68125
|
-
h += '<button class="aspect-btn" id="aspect-btn">';
|
|
68126
|
-
h += '<span id="aspect-btn-label">All orientations</span>';
|
|
68127
|
-
h += '<svg class="aspect-btn-chevron" width="11" height="11" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="2,4 6,8 10,4"/></svg>';
|
|
68128
|
-
h += '</button>';
|
|
68129
|
-
h += '<div class="aspect-menu" id="aspect-menu">';
|
|
68130
|
-
var aspects = [
|
|
68131
|
-
{ val: "", label: "All orientations", icon: '<svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="1" y="1" width="12" height="12" rx="1.5"/></svg>' },
|
|
68132
|
-
{ val: "landscape", label: "Landscape", icon: '<svg width="14" height="10" viewBox="0 0 14 10" fill="none" stroke="currentColor" stroke-width="1.5"><rect x=".75" y=".75" width="12.5" height="8.5" rx="1.5"/></svg>' },
|
|
68133
|
-
{ val: "portrait", label: "Portrait", icon: '<svg width="10" height="14" viewBox="0 0 10 14" fill="none" stroke="currentColor" stroke-width="1.5"><rect x=".75" y=".75" width="8.5" height="12.5" rx="1.5"/></svg>' },
|
|
68134
|
-
{ val: "square", label: "Square", icon: '<svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5"><rect x=".75" y=".75" width="10.5" height="10.5" rx="1.5"/></svg>' },
|
|
68135
|
-
];
|
|
68136
|
-
for (var ai = 0; ai < aspects.length; ai++) {
|
|
68137
|
-
var ao = aspects[ai];
|
|
68138
|
-
h += '<div class="aspect-option' + (ao.val === aspectFilter ? ' selected' : '') + '" data-value="' + ao.val + '">';
|
|
68139
|
-
h += '<span class="aspect-opt-icon">' + ao.icon + '</span>';
|
|
68140
|
-
h += ao.label;
|
|
68141
|
-
h += '<svg class="aspect-check" width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><polyline points="2,6 5,9 10,3"/></svg>';
|
|
68142
|
-
h += '</div>';
|
|
68143
|
-
}
|
|
68144
|
-
h += '</div></div></div>';
|
|
68145
|
-
|
|
68146
68010
|
// Grid
|
|
68147
68011
|
h += '<div class="grid" id="gallery-grid">';
|
|
68148
68012
|
for (var i = 0; i < allResources.length; i++) {
|
|
@@ -68191,8 +68055,8 @@ function render() {
|
|
|
68191
68055
|
if (url) {
|
|
68192
68056
|
h += '<div class="card-actions">';
|
|
68193
68057
|
h += '<button class="action-btn act-original" data-copy-original="' + i + '">Copy URL</button>';
|
|
68194
|
-
if (rt !== "raw") h += '<button class="action-btn act-optimized" data-copy-optimized="' + i + '"
|
|
68195
|
-
h += '<button class="action-btn act-download" data-download="' + i + '" title="Download"
|
|
68058
|
+
if (rt !== "raw") h += '<button class="action-btn act-optimized" data-copy-optimized="' + i + '">' + IC.zap + ' Optimized</button>';
|
|
68059
|
+
h += '<button class="action-btn act-download" data-download="' + i + '" title="Download">' + IC.arrowDown + '</button>';
|
|
68196
68060
|
h += '</div>';
|
|
68197
68061
|
}
|
|
68198
68062
|
|
|
@@ -68239,24 +68103,22 @@ function render() {
|
|
|
68239
68103
|
h += "</div>";
|
|
68240
68104
|
}
|
|
68241
68105
|
|
|
68242
|
-
// Spacer so select bar doesn't cover Load More
|
|
68243
|
-
h += '<div class="select-bar-spacer" id="select-bar-spacer" style="display:none"></div>';
|
|
68244
|
-
|
|
68245
68106
|
// Multi-select bar
|
|
68246
68107
|
h += '<div class="select-bar" id="select-bar">';
|
|
68247
68108
|
h += '<span class="select-count" id="select-count">0 selected</span>';
|
|
68248
68109
|
h += '<div class="bar-divider"></div>';
|
|
68249
|
-
h += '<button class="bar-btn bar-primary" id="bar-copy-optimized" style="display:none"
|
|
68110
|
+
h += '<button class="bar-btn bar-primary" id="bar-copy-optimized" style="display:none">' + IC.zap + ' Copy Optimized</button>';
|
|
68250
68111
|
h += '<button class="bar-btn bar-secondary" id="bar-copy-original">Copy Original</button>';
|
|
68251
|
-
h += '<button class="bar-btn bar-secondary" id="bar-download"
|
|
68112
|
+
h += '<button class="bar-btn bar-secondary" id="bar-download">' + IC.arrowDown + ' Download Selected</button>';
|
|
68252
68113
|
h += '<div class="bar-divider"></div>';
|
|
68253
|
-
h += '<button class="bar-btn bar-ghost" id="bar-clear"
|
|
68114
|
+
h += '<button class="bar-btn bar-ghost" id="bar-clear">' + IC.x + '</button>';
|
|
68254
68115
|
h += '</div>';
|
|
68255
68116
|
|
|
68256
68117
|
// Toast
|
|
68257
68118
|
h += '<div class="gallery-toast" id="gallery-toast"></div>';
|
|
68258
68119
|
|
|
68259
68120
|
root.innerHTML = h;
|
|
68121
|
+
renderThemeToggle();
|
|
68260
68122
|
|
|
68261
68123
|
// Re-apply selection state
|
|
68262
68124
|
selected.forEach(function(i) {
|
|
@@ -68290,37 +68152,16 @@ function attachEvents() {
|
|
|
68290
68152
|
_eventsAttached = true;
|
|
68291
68153
|
var root = document.getElementById("app");
|
|
68292
68154
|
|
|
68293
|
-
root.addEventListener("input", function(e) {
|
|
68294
|
-
if (e.target && e.target.id === "filter-input") handleFilter();
|
|
68295
|
-
});
|
|
68296
|
-
|
|
68297
|
-
document.addEventListener("click", function(e) {
|
|
68298
|
-
var dd = document.getElementById("aspect-dropdown");
|
|
68299
|
-
if (dd && !dd.contains(e.target)) {
|
|
68300
|
-
var menu = document.getElementById("aspect-menu");
|
|
68301
|
-
var btn = document.getElementById("aspect-btn");
|
|
68302
|
-
if (menu) menu.classList.remove("open");
|
|
68303
|
-
if (btn) btn.classList.remove("open");
|
|
68304
|
-
}
|
|
68305
|
-
});
|
|
68306
|
-
|
|
68307
68155
|
root.addEventListener("click", function(e) {
|
|
68308
68156
|
var el = e.target;
|
|
68309
68157
|
while (el && el !== root) {
|
|
68310
68158
|
if (el.id === "load-more-btn") { loadMore(); return; }
|
|
68311
68159
|
if (el.id === "refresh-gallery") { refreshGallery(); return; }
|
|
68312
68160
|
if (el.id === "select-all-btn") { toggleSelectAll(); return; }
|
|
68313
|
-
if (el.id === "filter-clear") { clearFilter(); return; }
|
|
68314
68161
|
if (el.id === "bar-copy-optimized") { copySelectedUrls("optimized"); return; }
|
|
68315
68162
|
if (el.id === "bar-copy-original") { copySelectedUrls("original"); return; }
|
|
68316
68163
|
if (el.id === "bar-download") { downloadSelected(); return; }
|
|
68317
68164
|
if (el.id === "bar-clear") { clearSelection(); return; }
|
|
68318
|
-
if (el.id === "aspect-btn" || el.parentElement && el.parentElement.id === "aspect-btn") {
|
|
68319
|
-
toggleAspectMenu(e); return;
|
|
68320
|
-
}
|
|
68321
|
-
if (el.classList && el.classList.contains("aspect-option")) {
|
|
68322
|
-
selectAspect(el.getAttribute("data-value") || ""); return;
|
|
68323
|
-
}
|
|
68324
68165
|
if (el.dataset && el.dataset.copyOriginal != null) {
|
|
68325
68166
|
e.stopPropagation();
|
|
68326
68167
|
copyAssetUrl("original", parseInt(el.dataset.copyOriginal, 10)); return;
|
|
@@ -68481,6 +68322,7 @@ function showFetchPrompt() {
|
|
|
68481
68322
|
h += '<button class="prompt-btn prompt-btn-primary" id="fetch-direct-btn">Fetch Directly</button>';
|
|
68482
68323
|
h += "</div></div>";
|
|
68483
68324
|
root.innerHTML = h;
|
|
68325
|
+
renderThemeToggle();
|
|
68484
68326
|
document.getElementById("fetch-direct-btn").addEventListener("click", function() { fetchDirect(); });
|
|
68485
68327
|
}
|
|
68486
68328
|
|
|
@@ -68558,7 +68400,6 @@ function refreshGallery() {
|
|
|
68558
68400
|
document.addEventListener("keydown", function(e) {
|
|
68559
68401
|
if (e.key === "Escape") {
|
|
68560
68402
|
if (document.querySelector(".modal-overlay")) { closeModal(); return; }
|
|
68561
|
-
if (filterQuery || aspectFilter) { clearFilter(); return; }
|
|
68562
68403
|
if (selected.size > 0) { clearSelection(); return; }
|
|
68563
68404
|
}
|
|
68564
68405
|
});
|
|
@@ -68590,6 +68431,7 @@ ${GALLERY_CSS}
|
|
|
68590
68431
|
<div class="gallery-toast" id="gallery-toast"></div>
|
|
68591
68432
|
|
|
68592
68433
|
<script>
|
|
68434
|
+
${SHARED_JS_ICONS}
|
|
68593
68435
|
${SHARED_JS_MCP_CLIENT}
|
|
68594
68436
|
${SHARED_JS_HELPERS}
|
|
68595
68437
|
${SHARED_JS_TOOLTIPS}
|
|
@@ -68643,16 +68485,6 @@ var ASSET_DETAILS_CSS = `
|
|
|
68643
68485
|
padding: 2px 7px; border-radius: 4px; border: 1px solid var(--cld-border);
|
|
68644
68486
|
}
|
|
68645
68487
|
|
|
68646
|
-
.open-link {
|
|
68647
|
-
padding: 6px 14px; border-radius: var(--cld-radius-sm);
|
|
68648
|
-
font-size: 12px; font-weight: 500; cursor: pointer;
|
|
68649
|
-
border: 1px solid var(--cld-accent); background: transparent;
|
|
68650
|
-
color: var(--cld-accent); font-family: inherit;
|
|
68651
|
-
transition: background 0.15s;
|
|
68652
|
-
white-space: nowrap; flex-shrink: 0;
|
|
68653
|
-
}
|
|
68654
|
-
.open-link:hover { background: var(--cld-accent-bg); }
|
|
68655
|
-
|
|
68656
68488
|
.hero-container {
|
|
68657
68489
|
position: relative; margin-bottom: var(--cld-sp-md);
|
|
68658
68490
|
border-radius: var(--cld-radius); overflow: hidden;
|
|
@@ -68713,9 +68545,9 @@ function renderPage(r) {
|
|
|
68713
68545
|
if (dur) h += '<span class="pill">' + dur + "</span>";
|
|
68714
68546
|
if (size) h += '<span class="pill">' + size + "</span>";
|
|
68715
68547
|
h += "</div></div>";
|
|
68716
|
-
h += '<div style="display:flex;gap:
|
|
68717
|
-
h += '<button class="
|
|
68718
|
-
|
|
68548
|
+
h += '<div id="header-actions" style="display:flex;gap:8px;flex-shrink:0;align-items:center">';
|
|
68549
|
+
if (url) h += '<button class="icon-btn" id="open-asset">Open</button>';
|
|
68550
|
+
h += '<button class="icon-btn icon-only" id="refresh-asset" title="Refresh">' + IC.refresh + '</button>';
|
|
68719
68551
|
h += "</div>";
|
|
68720
68552
|
h += "</div>";
|
|
68721
68553
|
|
|
@@ -68757,6 +68589,7 @@ function renderPage(r) {
|
|
|
68757
68589
|
h += "</div>";
|
|
68758
68590
|
|
|
68759
68591
|
root.innerHTML = h;
|
|
68592
|
+
renderThemeToggle();
|
|
68760
68593
|
|
|
68761
68594
|
// Event delegation
|
|
68762
68595
|
root.addEventListener("click", function handler(e) {
|
|
@@ -68802,6 +68635,7 @@ function showFetchPrompt() {
|
|
|
68802
68635
|
h += '<button class="prompt-btn prompt-btn-primary" id="fetch-direct-btn">Fetch Directly</button>';
|
|
68803
68636
|
h += "</div></div>";
|
|
68804
68637
|
root.innerHTML = h;
|
|
68638
|
+
renderThemeToggle();
|
|
68805
68639
|
document.getElementById("fetch-direct-btn").addEventListener("click", function() { fetchDirect(); });
|
|
68806
68640
|
}
|
|
68807
68641
|
|
|
@@ -68883,6 +68717,7 @@ ${ASSET_DETAILS_CSS}
|
|
|
68883
68717
|
<div id="app"><div class="status">Loading asset details…</div></div>
|
|
68884
68718
|
|
|
68885
68719
|
<script>
|
|
68720
|
+
${SHARED_JS_ICONS}
|
|
68886
68721
|
${SHARED_JS_MCP_CLIENT}
|
|
68887
68722
|
${SHARED_JS_HELPERS}
|
|
68888
68723
|
${SHARED_JS_TOOLTIPS}
|
|
@@ -69122,15 +68957,8 @@ var uploadJsonSchema, rtJsonSchema, allSchemaProperties, rtCopy, SCHEMA_JSON, UP
|
|
|
69122
68957
|
.upload-header h1 {
|
|
69123
68958
|
font-size: var(--cld-font-sm); font-weight: 600; color: var(--cld-text);
|
|
69124
68959
|
}
|
|
69125
|
-
.upload-header-icon {
|
|
69126
|
-
.upload-header {
|
|
69127
|
-
.back-link {
|
|
69128
|
-
position: absolute; top: -2px; right: 0;
|
|
69129
|
-
background: none; border: none; cursor: pointer;
|
|
69130
|
-
color: var(--cld-accent); font-size: var(--cld-font-xs);
|
|
69131
|
-
padding: 2px 6px; border-radius: 4px;
|
|
69132
|
-
}
|
|
69133
|
-
.back-link:hover { text-decoration: underline; background: var(--cld-accent-bg); }
|
|
68960
|
+
.upload-header-icon { display: flex; align-items: center; justify-content: center; }
|
|
68961
|
+
.upload-header-icon svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
|
|
69134
68962
|
|
|
69135
68963
|
.upload-result .detail-section { padding: 14px 16px; }
|
|
69136
68964
|
.upload-result .detail-section:first-child { padding-top: 0; }
|
|
@@ -69581,16 +69409,18 @@ function renderPicker() {
|
|
|
69581
69409
|
var h = "";
|
|
69582
69410
|
|
|
69583
69411
|
h += '<div class="upload-header">';
|
|
69412
|
+
h += '<span class="upload-header-icon icon-accent">' + IC.uploadCloud + '</span>';
|
|
69413
|
+
h += "<h1>Upload to Cloudinary</h1>";
|
|
69414
|
+
h += '<div id="header-actions" style="display:flex;align-items:center;gap:6px;margin-left:auto">';
|
|
69584
69415
|
if (lastResult) {
|
|
69585
|
-
h += '<button class="
|
|
69416
|
+
h += '<button class="icon-btn" id="back-to-result-btn">' + IC.chevronLeft + ' Back</button>';
|
|
69586
69417
|
}
|
|
69587
|
-
h += '
|
|
69588
|
-
h += "<h1>Upload to Cloudinary</h1>";
|
|
69418
|
+
h += '</div>';
|
|
69589
69419
|
h += "</div>";
|
|
69590
69420
|
|
|
69591
69421
|
if (stagedFile) {
|
|
69592
69422
|
h += '<div class="upload-staged">';
|
|
69593
|
-
h += '<div class="upload-staged-icon"
|
|
69423
|
+
h += '<div class="upload-staged-icon">' + IC.file + '</div>';
|
|
69594
69424
|
h += '<div class="upload-staged-info">';
|
|
69595
69425
|
h += '<div class="upload-staged-name">' + esc(stagedFile.name) + "</div>";
|
|
69596
69426
|
if (stagedFile.size) {
|
|
@@ -69601,11 +69431,11 @@ function renderPicker() {
|
|
|
69601
69431
|
h += '<div class="upload-staged-meta">Remote URL</div>';
|
|
69602
69432
|
}
|
|
69603
69433
|
h += "</div>";
|
|
69604
|
-
h += '<button class="upload-staged-clear" id="clear-staged-btn" title="Remove"
|
|
69434
|
+
h += '<button class="upload-staged-clear icon-btn icon-only" id="clear-staged-btn" title="Remove">' + IC.x + '</button>';
|
|
69605
69435
|
h += "</div>";
|
|
69606
69436
|
} else {
|
|
69607
69437
|
h += '<div class="upload-zone" id="drop-zone">';
|
|
69608
|
-
h += '<div class="upload-zone-icon"
|
|
69438
|
+
h += '<div class="upload-zone-icon">' + IC.folderOpen + '</div>';
|
|
69609
69439
|
h += '<div class="upload-zone-text">Drag & drop a file here</div>';
|
|
69610
69440
|
h += '<div class="upload-zone-hint">Images, videos, PDFs, and other files up to 60 MB</div>';
|
|
69611
69441
|
h += '<button class="upload-zone-btn" id="browse-btn">Browse Files</button>';
|
|
@@ -69629,6 +69459,7 @@ function renderPicker() {
|
|
|
69629
69459
|
}
|
|
69630
69460
|
|
|
69631
69461
|
root.innerHTML = h;
|
|
69462
|
+
renderThemeToggle();
|
|
69632
69463
|
|
|
69633
69464
|
var backBtn = document.getElementById("back-to-result-btn");
|
|
69634
69465
|
if (backBtn && lastResult) {
|
|
@@ -69708,12 +69539,13 @@ function renderUploading(name, meta) {
|
|
|
69708
69539
|
var h = "";
|
|
69709
69540
|
|
|
69710
69541
|
h += '<div class="upload-header">';
|
|
69711
|
-
h += '<span class="upload-header-icon"
|
|
69712
|
-
h +=
|
|
69542
|
+
h += '<span class="upload-header-icon icon-accent">' + IC.uploadCloud + '</span>';
|
|
69543
|
+
h += '<h1>Uploading…</h1>';
|
|
69544
|
+
h += '<div id="header-actions" style="display:flex;align-items:center;gap:6px;margin-left:auto"></div>';
|
|
69713
69545
|
h += "</div>";
|
|
69714
69546
|
|
|
69715
69547
|
h += '<div class="upload-preview">';
|
|
69716
|
-
h += '<div class="upload-preview-icon"
|
|
69548
|
+
h += '<div class="upload-preview-icon">' + IC.file + '</div>';
|
|
69717
69549
|
h += '<div class="upload-preview-info">';
|
|
69718
69550
|
h += '<div class="upload-preview-name">' + esc(name) + "</div>";
|
|
69719
69551
|
h += '<div class="upload-preview-meta">' + esc(meta) + "</div>";
|
|
@@ -69725,6 +69557,7 @@ function renderUploading(name, meta) {
|
|
|
69725
69557
|
h += "</div>";
|
|
69726
69558
|
|
|
69727
69559
|
root.innerHTML = h;
|
|
69560
|
+
renderThemeToggle();
|
|
69728
69561
|
animateProgress();
|
|
69729
69562
|
}
|
|
69730
69563
|
|
|
@@ -69778,7 +69611,7 @@ function renderUploadError(title, msg) {
|
|
|
69778
69611
|
var header = document.querySelector(".upload-header h1");
|
|
69779
69612
|
if (header) header.textContent = title;
|
|
69780
69613
|
var icon = document.querySelector(".upload-header-icon");
|
|
69781
|
-
if (icon) icon.
|
|
69614
|
+
if (icon) { icon.innerHTML = IC.alertTriangle; icon.className = "upload-header-icon icon-warning"; }
|
|
69782
69615
|
|
|
69783
69616
|
var safeMsg = esc(msg).replace(/\\n/g, "<br>");
|
|
69784
69617
|
var h = '<div class="upload-error-msg">' + safeMsg + "</div>";
|
|
@@ -69790,14 +69623,16 @@ function renderUploadError(title, msg) {
|
|
|
69790
69623
|
var root = document.getElementById("app");
|
|
69791
69624
|
var safeMsg = esc(msg).replace(/\\n/g, "<br>");
|
|
69792
69625
|
var h = '<div class="upload-header">';
|
|
69793
|
-
h += '<span class="upload-header-icon"
|
|
69626
|
+
h += '<span class="upload-header-icon icon-warning">' + IC.alertTriangle + '</span>';
|
|
69794
69627
|
h += "<h1>" + esc(title) + "</h1>";
|
|
69628
|
+
h += '<div id="header-actions" style="display:flex;align-items:center;gap:6px;margin-left:auto"></div>';
|
|
69795
69629
|
h += "</div>";
|
|
69796
69630
|
h += '<div class="upload-error-msg">' + safeMsg + "</div>";
|
|
69797
69631
|
h += '<div class="upload-another" style="margin-top:14px;text-align:center">';
|
|
69798
69632
|
h += '<button class="prompt-btn prompt-btn-primary" id="retry-upload-btn">Try from App</button>';
|
|
69799
69633
|
h += "</div>";
|
|
69800
69634
|
root.innerHTML = h;
|
|
69635
|
+
renderThemeToggle();
|
|
69801
69636
|
}
|
|
69802
69637
|
|
|
69803
69638
|
var btn = document.getElementById("retry-upload-btn");
|
|
@@ -69842,8 +69677,9 @@ function renderLocalFileNeeded(expectedName, errMsg) {
|
|
|
69842
69677
|
var classified = classifyFileError(errMsg);
|
|
69843
69678
|
var root = document.getElementById("app");
|
|
69844
69679
|
var h = '<div class="upload-header">';
|
|
69845
|
-
h += '<span class="upload-header-icon"
|
|
69680
|
+
h += '<span class="upload-header-icon icon-accent">' + IC.folderOpen + '</span>';
|
|
69846
69681
|
h += "<h1>" + esc(classified.title) + "</h1>";
|
|
69682
|
+
h += '<div id="header-actions" style="display:flex;align-items:center;gap:6px;margin-left:auto"></div>';
|
|
69847
69683
|
h += "</div>";
|
|
69848
69684
|
h += '<div class="prompt" style="margin-bottom:16px">';
|
|
69849
69685
|
h += '<div class="prompt-desc">The file <strong>' + esc(expectedName)
|
|
@@ -69858,13 +69694,14 @@ function renderLocalFileNeeded(expectedName, errMsg) {
|
|
|
69858
69694
|
}
|
|
69859
69695
|
h += "</div>";
|
|
69860
69696
|
h += '<div class="upload-zone" id="drop-zone">';
|
|
69861
|
-
h += '<div class="upload-zone-icon"
|
|
69697
|
+
h += '<div class="upload-zone-icon">' + IC.folderOpen + '</div>';
|
|
69862
69698
|
h += '<div class="upload-zone-text">Drop <strong>' + esc(expectedName) + "</strong> here</div>";
|
|
69863
69699
|
h += '<div class="upload-zone-hint">Or click to browse your files</div>';
|
|
69864
69700
|
h += '<button class="upload-zone-btn" id="browse-btn">Browse Files</button>';
|
|
69865
69701
|
h += '<input type="file" id="file-input" style="display:none">';
|
|
69866
69702
|
h += "</div>";
|
|
69867
69703
|
root.innerHTML = h;
|
|
69704
|
+
renderThemeToggle();
|
|
69868
69705
|
|
|
69869
69706
|
function onFileSelected(file) {
|
|
69870
69707
|
var reader = new FileReader();
|
|
@@ -69977,8 +69814,9 @@ function renderResult(r) {
|
|
|
69977
69814
|
var h = "";
|
|
69978
69815
|
|
|
69979
69816
|
h += '<div class="upload-header">';
|
|
69980
|
-
h += '<span class="upload-header-icon
|
|
69817
|
+
h += '<span class="upload-header-icon ' + (isPending ? "icon-accent" : "icon-success") + '">' + (isPending ? IC.clock : IC.checkCircle) + '</span>';
|
|
69981
69818
|
h += "<h1>" + (isPending ? "Upload Queued" : "Upload Complete") + "</h1>";
|
|
69819
|
+
h += '<div id="header-actions" style="display:flex;align-items:center;gap:6px;margin-left:auto"></div>';
|
|
69982
69820
|
h += "</div>";
|
|
69983
69821
|
|
|
69984
69822
|
h += '<div class="upload-result">';
|
|
@@ -70039,6 +69877,7 @@ function renderResult(r) {
|
|
|
70039
69877
|
h += "</div></div>";
|
|
70040
69878
|
|
|
70041
69879
|
root.innerHTML = h;
|
|
69880
|
+
renderThemeToggle();
|
|
70042
69881
|
|
|
70043
69882
|
root.addEventListener("click", function handler(e) {
|
|
70044
69883
|
var el = e.target;
|
|
@@ -70173,6 +70012,7 @@ ${UPLOAD_CSS}
|
|
|
70173
70012
|
<div id="app"><div class="status">Preparing upload…</div></div>
|
|
70174
70013
|
|
|
70175
70014
|
<script>
|
|
70015
|
+
${SHARED_JS_ICONS}
|
|
70176
70016
|
${SHARED_JS_MCP_CLIENT}
|
|
70177
70017
|
${SHARED_JS_HELPERS}
|
|
70178
70018
|
${SHARED_JS_TOOLTIPS}
|
|
@@ -70192,7 +70032,12 @@ function appResourceContent(uri, html) {
|
|
|
70192
70032
|
uri: uri.toString(),
|
|
70193
70033
|
mimeType: MCP_APP_MIME_TYPE,
|
|
70194
70034
|
text: html,
|
|
70195
|
-
_meta: {
|
|
70035
|
+
_meta: {
|
|
70036
|
+
ui: {
|
|
70037
|
+
csp: { resourceDomains: CSP_RESOURCE_DOMAINS },
|
|
70038
|
+
permissions: { clipboardWrite: {} }
|
|
70039
|
+
}
|
|
70040
|
+
}
|
|
70196
70041
|
}]
|
|
70197
70042
|
};
|
|
70198
70043
|
}
|
|
@@ -73360,11 +73205,12 @@ var init_searchparameters = __esm(() => {
|
|
|
73360
73205
|
"duration"
|
|
73361
73206
|
]);
|
|
73362
73207
|
SearchParametersRange$zodSchema = object({
|
|
73363
|
-
from: number2().optional().describe("Start of the range (inclusive)"),
|
|
73364
|
-
|
|
73208
|
+
from: number2().optional().describe("Start of the range (inclusive). At least one of `from` / `to` is required."),
|
|
73209
|
+
key: string2().describe("A label for the bucket, returned in the aggregation response. 1–20 chars, alphanumeric plus `-` and `_`."),
|
|
73210
|
+
to: number2().optional().describe("End of the range (exclusive). At least one of `from` / `to` is required.")
|
|
73365
73211
|
});
|
|
73366
73212
|
Aggregate$zodSchema = object({
|
|
73367
|
-
ranges: array(lazy(() => SearchParametersRange$zodSchema)),
|
|
73213
|
+
ranges: array(lazy(() => SearchParametersRange$zodSchema)).describe("One or more ranges for the numeric field. Each range must include a `key` label and at least one of `from` / `to`.\n"),
|
|
73368
73214
|
type: Type$zodSchema
|
|
73369
73215
|
});
|
|
73370
73216
|
AggregateEnum$zodSchema = _enum2([
|
|
@@ -73375,7 +73221,8 @@ var init_searchparameters = __esm(() => {
|
|
|
73375
73221
|
AggregateUnion$zodSchema = union([
|
|
73376
73222
|
array(AggregateEnum$zodSchema),
|
|
73377
73223
|
array(lazy(() => Aggregate$zodSchema))
|
|
73378
|
-
]).describe(
|
|
73224
|
+
]).describe(`Fields or ranges to aggregate search results by. Requires a Tier 2 search plan; on Tier 1 the field is accepted but aggregations are omitted from the response.
|
|
73225
|
+
`);
|
|
73379
73226
|
WithField$zodSchema = _enum2([
|
|
73380
73227
|
"context",
|
|
73381
73228
|
"tags",
|
|
@@ -73389,19 +73236,20 @@ var init_searchparameters = __esm(() => {
|
|
|
73389
73236
|
aggregate: union([
|
|
73390
73237
|
array(AggregateEnum$zodSchema),
|
|
73391
73238
|
array(lazy(() => Aggregate$zodSchema))
|
|
73392
|
-
]).optional().describe(
|
|
73393
|
-
|
|
73239
|
+
]).optional().describe(`Fields or ranges to aggregate search results by. Requires a Tier 2 search plan; on Tier 1 the field is accepted but aggregations are omitted from the response.
|
|
73240
|
+
`),
|
|
73241
|
+
expression: string2().optional().describe('The Lucene-like search expression. Supports token match (`:`), exact match (`=`), trailing `*` for prefix match, ranges (`[a TO b]`, `{a TO b}`), and comparisons (`>`, `<`, `>=`, `<=`). Combine terms with uppercase `AND`, `OR`, `NOT`, or `+`/`-`. `NOT` must appear between clauses — a leading `NOT` is a parse error; use `-field:value` to negate the first clause. Group with parentheses.\n\nWrap values containing spaces, colons, or other reserved characters (`! ( ) { } [ ] ^ ~ ? \\ = & < > |`) in double quotes, e.g. `tags:"service:mantels"`, `aspect_ratio:"16:9"`. Send raw `<`/`>`, never HTML-escaped.\n\nWildcards are prefix-only (trailing `*`). A bare `*` (e.g. `folder:*`, `context.alt:*`, `metadata.key:*`, `tags:*`, `-tags:*`) is a parse error — there is no "has any value" / presence probe. Either drop the clause, use a concrete prefix, or filter on a known token.\n\nDates: ISO-8601 in quotes, or relative shorthand `1h`, `1d`, `1w`, `1m`, `1y` (`uploaded_at>1d`, `created_at:[4w TO 1w]`).\n\nSupported fields: `public_id`, `asset_id`, `filename`, `display_name`, `folder` / `asset_folder` (singular, not `folders`), `tags`, `context.<key>`, `metadata.<external_id>`, `resource_type`, `type`, `format`, `bytes`, `width`, `height`, `duration`, `pages`, `aspect_ratio`, `transparent`, `grayscale`, `status`, `moderation_status`, `moderation_kind`, `uploaded_at`, `created_at`, `taken_at`, `updated_at`, `last_updated.<kind>`, `face_count`, `illustration_score`, `quality_score`. Fields under `image_metadata.*`, `image_analysis.*`, `quality_analysis.*`, and `accessibility_analysis.*` also require the matching `with_field` to be returned in the response.\n\nSee the [search expressions guide](https://cloudinary.com/documentation/search_expressions.md) for the full reference.\n'),
|
|
73394
73242
|
fields: string2().optional().describe(`A comma-separated list of fields to include in the response.
|
|
73395
73243
|
Notes:
|
|
73396
73244
|
- This parameter takes precedence over the with_field parameter, so if you want any additional asset attributes returned, make sure to also include them in this list (e.g., tags or context).
|
|
73397
73245
|
- The following fields are always included in the response: public_id, asset_id, asset_folder, created_at, status, type, and resource_type.
|
|
73398
73246
|
`),
|
|
73399
|
-
max_results: int().optional().describe("The maximum number of results to return. Default - 50. Maximum - 500
|
|
73247
|
+
max_results: int().optional().describe("The maximum number of results to return. Default - 50. Maximum - 500.\nSet to `0` to get only `total_count` and `aggregations` without any resources in the response — useful for counting or aggregation-only queries.\n"),
|
|
73400
73248
|
next_cursor: string2().optional().describe("The cursor value to get the next page of results. Available when a previous search returned more results than max_results."),
|
|
73401
73249
|
sort_by: array(record(string2(), DirectionEnum$zodSchema)).optional().describe(`An array of single-key objects mapping a field to a sort direction. Each object must contain exactly one field name mapped to 'asc' or 'desc'.
|
|
73402
73250
|
Default: [{"created_at": "desc"}].
|
|
73403
73251
|
`),
|
|
73404
|
-
with_field: array(WithField$zodSchema).optional().describe("The additional
|
|
73252
|
+
with_field: array(WithField$zodSchema).optional().describe("The additional asset attributes to include in each search result. The `fields` parameter takes precedence over this parameter. `image_metadata`, `image_analysis`, and `metadata` require a Tier 2 search plan.\n")
|
|
73405
73253
|
}).describe("Common parameters for resource search operations.");
|
|
73406
73254
|
});
|
|
73407
73255
|
|
|
@@ -73499,9 +73347,53 @@ var init_searchSearchAssets2 = __esm(() => {
|
|
|
73499
73347
|
|
|
73500
73348
|
Returns a list of resources matching the specified search criteria.
|
|
73501
73349
|
|
|
73502
|
-
Uses Lucene-like query language to
|
|
73503
|
-
|
|
73504
|
-
|
|
73350
|
+
Uses a Lucene-like query language to filter assets by descriptive attributes (\`public_id\`, \`asset_id\`, \`filename\`, \`display_name\`, \`folder\` / \`asset_folder\`, \`tags\`, \`context.<key>\`), file details (\`resource_type\`, \`type\`, \`format\`, \`bytes\`, \`width\`, \`height\`, \`duration\`, \`pages\`, \`aspect_ratio\`, \`transparent\`, \`grayscale\`), lifecycle dates (\`uploaded_at\`, \`created_at\`, \`taken_at\`, \`updated_at\`, \`last_updated.<kind>\`), moderation and lifecycle state (\`status\`, \`moderation_status\`, \`moderation_kind\`), embedded data (\`image_metadata.*\`), structured metadata (\`metadata.<external_id>\`), and analysis fields (\`face_count\`, \`colors\`, \`quality_score\`, \`illustration_score\`, \`accessibility_analysis.*\`). Supports sorting, aggregate counts, and complex boolean expressions. See the \`expression\` parameter for the full field reference.
|
|
73351
|
+
|
|
73352
|
+
## Expression syntax
|
|
73353
|
+
|
|
73354
|
+
- **Match**: \`field:value\` (token match) or \`field=value\` (exact match). Examples: \`tags:shirt\`, \`tags=cotton\`.
|
|
73355
|
+
- **Comparisons**: \`>\`, \`<\`, \`>=\`, \`<=\` for numbers and dates. Example: \`bytes>10000000\`.
|
|
73356
|
+
- **Ranges**: \`field:[from TO to]\` inclusive, \`field:{from TO to}\` exclusive. Example: \`width:{200 TO 1028}\`.
|
|
73357
|
+
- **Booleans**: \`AND\`, \`OR\`, \`NOT\` (uppercase), or \`+\` (must), \`-\` (must not). \`NOT\` must appear between clauses — a bare leading \`NOT\` is a parse error; use \`-field:value\` to negate the first clause. Group with parentheses: \`(shirt OR pants) AND clothes\`.
|
|
73358
|
+
- **Wildcards**: trailing \`*\` only, for prefix match (\`public_id:shoes_*\`, \`format:jp*\`, \`tags:shirt*\`). Not supported on \`folder\`, \`asset_folder\`, \`resource_type\`, or \`type\`. Leading \`*\`, middle \`*\`, \`?\`, and bare \`*\` (\`folder:*\`, \`context.alt:*\`) are all parse errors — wildcards cannot be used as a "field is present" probe.
|
|
73359
|
+
- **Tokenized vs exact fields**: \`tags\`, \`filename\`, \`display_name\`, \`context.<key>\`, and \`metadata.<id>\` match on tokens split by whitespace and punctuation — \`tags:analysis\` matches the tag \`full-analysis\`. \`public_id\`, \`folder\`, \`asset_folder\`, and \`format\` match the whole value — \`public_id:dog\` will not match \`dog_pldcwy\`; use \`public_id="dog_pldcwy"\` (exact) or \`public_id:dog*\` (prefix). These exact-match fields still accept a trailing \`*\` for prefix match (except \`folder\` / \`asset_folder\`, where wildcards are ignored).
|
|
73360
|
+
- **Dates**: ISO-8601 in quotes (\`uploaded_at>"2024-01-15"\`) or relative shorthand \`Nh\`, \`Nd\`, \`Nw\`, \`Nm\`, \`Ny\` (\`uploaded_at>1d\`, \`created_at:[4w TO 1w]\`). Send raw \`<\`/\`>\`, never HTML-escaped.
|
|
73361
|
+
- **Quoting**: wrap any value containing a space, colon, or other reserved character (\`! ( ) { } [ ] ^ ~ ? \\ = & < > |\`) in double quotes, or escape each character with \`\\\`. Examples: \`tags:"service:mantels"\`, \`aspect_ratio:"16:9"\`, \`folder:"My Folder"\`.
|
|
73362
|
+
|
|
73363
|
+
## Common mistakes
|
|
73364
|
+
|
|
73365
|
+
- Use \`folder:\` or \`asset_folder:\` (singular); \`folders:\`, \`asset_folder_id:\`, and other invented variants are not valid fields. Pass the exact folder name — wildcards do not apply here.
|
|
73366
|
+
- There is no "has any value" / presence probe. \`folder:*\`, \`metadata.alt:*\`, \`context.key:*\`, \`tags:*\`, and \`-tags:*\` are all parse errors. See *"Which assets have any value for \`metadata.<id>\`?"* under **Common tasks** for workarounds.
|
|
73367
|
+
- \`NOT foo AND bar\` is a parse error. Write it as \`bar AND NOT foo\` or \`-foo AND bar\`, and keep every \`NOT\` between two clauses (\`a AND NOT b AND NOT c\` is fine; \`NOT b AND NOT c …\` is not).
|
|
73368
|
+
- \`public_id:dog\` will not match \`dog_pldcwy\`. Use \`public_id="dog_pldcwy"\` (exact) or \`public_id:dog*\` (prefix).
|
|
73369
|
+
- \`tags=service:mantels\` fails because the unquoted colon is parsed as a field separator. Use \`tags="service:mantels"\` or \`tags=service\\:mantels\`.
|
|
73370
|
+
- Do not HTML-escape operators. Send \`uploaded_at<1h\`, not \`uploaded_at<1h\`.
|
|
73371
|
+
- Do not leave an operand empty (e.g. \`tags: AND -tags:foo\`). Omit the empty clause entirely.
|
|
73372
|
+
|
|
73373
|
+
## Tips
|
|
73374
|
+
|
|
73375
|
+
- Set \`max_results: 0\` to return only \`total_count\` and \`aggregations\` without any resource payload — useful for counts and aggregation-only queries.
|
|
73376
|
+
- \`total_count\` is always present in the response; prefer it over running an aggregation just to get a count.
|
|
73377
|
+
- \`aggregate\` (both simple and range variants) and the \`metadata\`, \`image_metadata\`, \`image_analysis\` values of \`with_field\` require a Tier 2 search plan.
|
|
73378
|
+
- Range aggregations require each range to include a \`key\` label (1–20 chars, \`[a-zA-Z0-9_-]+\`) and at least one of \`from\` / \`to\`.
|
|
73379
|
+
|
|
73380
|
+
## Common tasks
|
|
73381
|
+
|
|
73382
|
+
- **Count matching assets** — put the filter in \`expression\` with \`max_results: 0\` and read \`total_count\` from the response. Works on every tier; no \`aggregate\` needed.
|
|
73383
|
+
- **Preview one matching asset** — set \`max_results: 1\`; add \`with_field: ["tags", "context"]\` (or \`metadata\`, Tier 2) to inspect values. Prefer this over fetching and scanning a full page.
|
|
73384
|
+
- **Distribution of values for a field** — Tier 2: \`aggregate: [format|resource_type|type]\` for enum counts, or range aggregations on \`bytes\`, \`image_pixels\`, \`video_pixels\`, or \`duration\`. Tier 1 fallback: run N small queries with \`max_results: 0\`, one per candidate value, and read \`total_count\` from each.
|
|
73385
|
+
- **"Which assets have any value for \`metadata.<id>\`?"** — not expressible directly (\`metadata.X:*\` is a parse error; there is no presence probe). Workarounds: (a) if the field has a known value set, enumerate — \`metadata.region:(apac OR emea OR amer)\`; (b) query broadly with \`with_field: ["metadata"]\` (Tier 2) and filter client-side for entries where the field is set; (c) at ingest time, attach a sentinel tag whenever the field is set, then search by that tag.
|
|
73386
|
+
- **Newest / largest N** — keep the filter in \`expression\` and sort explicitly: \`sort_by: [{uploaded_at: "desc"}]\` with \`max_results: 10\`.
|
|
73387
|
+
- **Filter by folder** — both \`asset_folder:"parent/child"\` and \`folder:"parent/child"\` match an exact folder path; there is no wildcard or "contains". To query across multiple folders, enumerate: \`asset_folder:("campaigns/2024" OR "campaigns/2025")\`.
|
|
73388
|
+
- **Filter by metadata when you only know the label** — first call \`list-metadata-fields\` to resolve the label to an \`external_id\`, then query \`metadata.<external_id>:value\`.
|
|
73389
|
+
- **Multiple independent filters in one turn** — prefer one \`expression\` with \`OR\` / parentheses over firing many parallel calls: \`metadata.region:apac OR metadata.region:emea\` in a single request is faster and more reliable than two parallel requests.
|
|
73390
|
+
|
|
73391
|
+
## Examples
|
|
73392
|
+
|
|
73393
|
+
- \`tags:shirt AND uploaded_at>1d\`
|
|
73394
|
+
- \`resource_type:image AND bytes>1000000 AND (format:png OR format:jpg)\`
|
|
73395
|
+
- \`folder:products AND context.category:electronics\`
|
|
73396
|
+
- \`tags:"service:mantels" AND -tags:discontinued\`
|
|
73505
73397
|
`,
|
|
73506
73398
|
scopes: ["librarian"],
|
|
73507
73399
|
annotations: {
|
|
@@ -74056,7 +73948,7 @@ A report on the status of product environment usage, including storage, credits,
|
|
|
74056
73948
|
function createMCPServer(deps) {
|
|
74057
73949
|
const server = new McpServer({
|
|
74058
73950
|
name: "CloudinaryAssetMgmt",
|
|
74059
|
-
version: "0.9.
|
|
73951
|
+
version: "0.9.2"
|
|
74060
73952
|
});
|
|
74061
73953
|
const getClient = deps.getSDK || (() => new CloudinaryAssetMgmtCore({
|
|
74062
73954
|
security: deps.security,
|
|
@@ -74273,14 +74165,7 @@ Lists the folders that match the specified search expression. Limited to 2000 re
|
|
|
74273
74165
|
},
|
|
74274
74166
|
{
|
|
74275
74167
|
name: "search-assets",
|
|
74276
|
-
description:
|
|
74277
|
-
|
|
74278
|
-
Returns a list of resources matching the specified search criteria.
|
|
74279
|
-
|
|
74280
|
-
Uses Lucene-like query language to search by descriptive attributes (public_id, filename, folder, tags, context), file details (resource_type, format, bytes, width, height), embedded data (image_metadata), and analyzed data (face_count, colors, quality_score). Supports aggregate counts and complex Boolean expressions.
|
|
74281
|
-
|
|
74282
|
-
Examples: tags:shirt AND uploaded_at>1d, resource_type:image AND bytes>1mb, folder:products OR context.category:electronics
|
|
74283
|
-
`
|
|
74168
|
+
description: "Provides a powerful query interface to filter and retrieve assets and their details\n\nReturns a list of resources matching the specified search criteria.\n\nUses a Lucene-like query language to filter assets by descriptive attributes (`public_id`, `asset_id`, `filename`, `display_name`, `folder` / `asset_folder`, `tags`, `context.<key>`), file details (`resource_type`, `type`, `format`, `bytes`, `width`, `height`, `duration`, `pages`, `aspect_ratio`, `transparent`, `grayscale`), lifecycle dates (`uploaded_at`, `created_at`, `taken_at`, `updated_at`, `last_updated.<kind>`), moderation and lifecycle state (`status`, `moderation_status`, `moderation_kind`), embedded data (`image_metadata.*`), structured metadata (`metadata.<external_id>`), and analysis fields (`face_count`, `colors`, `quality_score`, `illustration_score`, `accessibility_analysis.*`). Supports sorting, aggregate counts, and complex boolean expressions. See the `expression` parameter for the full field reference.\n\n## Expression syntax\n\n- **Match**: `field:value` (token match) or `field=value` (exact match). Examples: `tags:shirt`, `tags=cotton`.\n- **Comparisons**: `>`, `<`, `>=`, `<=` for numbers and dates. Example: `bytes>10000000`.\n- **Ranges**: `field:[from TO to]` inclusive, `field:{from TO to}` exclusive. Example: `width:{200 TO 1028}`.\n- **Booleans**: `AND`, `OR`, `NOT` (uppercase), or `+` (must), `-` (must not). `NOT` must appear between clauses — a bare leading `NOT` is a parse error; use `-field:value` to negate the first clause. Group with parentheses: `(shirt OR pants) AND clothes`.\n- **Wildcards**: trailing `*` only, for prefix match (`public_id:shoes_*`, `format:jp*`, `tags:shirt*`). Not supported on `folder`, `asset_folder`, `resource_type`, or `type`. Leading `*`, middle `*`, `?`, and bare `*` (`folder:*`, `context.alt:*`) are all parse errors — wildcards cannot be used as a \"field is present\" probe.\n- **Tokenized vs exact fields**: `tags`, `filename`, `display_name`, `context.<key>`, and `metadata.<id>` match on tokens split by whitespace and punctuation — `tags:analysis` matches the tag `full-analysis`. `public_id`, `folder`, `asset_folder`, and `format` match the whole value — `public_id:dog` will not match `dog_pldcwy`; use `public_id=\"dog_pldcwy\"` (exact) or `public_id:dog*` (prefix). These exact-match fields still accept a trailing `*` for prefix match (except `folder` / `asset_folder`, where wildcards are ignored).\n- **Dates**: ISO-8601 in quotes (`uploaded_at>\"2024-01-15\"`) or relative shorthand `Nh`, `Nd`, `Nw`, `Nm`, `Ny` (`uploaded_at>1d`, `created_at:[4w TO 1w]`). Send raw `<`/`>`, never HTML-escaped.\n- **Quoting**: wrap any value containing a space, colon, or other reserved character (`! ( ) { } [ ] ^ ~ ? \\ = & < > |`) in double quotes, or escape each character with `\\`. Examples: `tags:\"service:mantels\"`, `aspect_ratio:\"16:9\"`, `folder:\"My Folder\"`.\n\n## Common mistakes\n\n- Use `folder:` or `asset_folder:` (singular); `folders:`, `asset_folder_id:`, and other invented variants are not valid fields. Pass the exact folder name — wildcards do not apply here.\n- There is no \"has any value\" / presence probe. `folder:*`, `metadata.alt:*`, `context.key:*`, `tags:*`, and `-tags:*` are all parse errors. See *\"Which assets have any value for `metadata.<id>`?\"* under **Common tasks** for workarounds.\n- `NOT foo AND bar` is a parse error. Write it as `bar AND NOT foo` or `-foo AND bar`, and keep every `NOT` between two clauses (`a AND NOT b AND NOT c` is fine; `NOT b AND NOT c …` is not).\n- `public_id:dog` will not match `dog_pldcwy`. Use `public_id=\"dog_pldcwy\"` (exact) or `public_id:dog*` (prefix).\n- `tags=service:mantels` fails because the unquoted colon is parsed as a field separator. Use `tags=\"service:mantels\"` or `tags=service\\:mantels`.\n- Do not HTML-escape operators. Send `uploaded_at<1h`, not `uploaded_at<1h`.\n- Do not leave an operand empty (e.g. `tags: AND -tags:foo`). Omit the empty clause entirely.\n\n## Tips\n\n- Set `max_results: 0` to return only `total_count` and `aggregations` without any resource payload — useful for counts and aggregation-only queries.\n- `total_count` is always present in the response; prefer it over running an aggregation just to get a count.\n- `aggregate` (both simple and range variants) and the `metadata`, `image_metadata`, `image_analysis` values of `with_field` require a Tier 2 search plan.\n- Range aggregations require each range to include a `key` label (1–20 chars, `[a-zA-Z0-9_-]+`) and at least one of `from` / `to`.\n\n## Common tasks\n\n- **Count matching assets** — put the filter in `expression` with `max_results: 0` and read `total_count` from the response. Works on every tier; no `aggregate` needed.\n- **Preview one matching asset** — set `max_results: 1`; add `with_field: [\"tags\", \"context\"]` (or `metadata`, Tier 2) to inspect values. Prefer this over fetching and scanning a full page.\n- **Distribution of values for a field** — Tier 2: `aggregate: [format|resource_type|type]` for enum counts, or range aggregations on `bytes`, `image_pixels`, `video_pixels`, or `duration`. Tier 1 fallback: run N small queries with `max_results: 0`, one per candidate value, and read `total_count` from each.\n- **\"Which assets have any value for `metadata.<id>`?\"** — not expressible directly (`metadata.X:*` is a parse error; there is no presence probe). Workarounds: (a) if the field has a known value set, enumerate — `metadata.region:(apac OR emea OR amer)`; (b) query broadly with `with_field: [\"metadata\"]` (Tier 2) and filter client-side for entries where the field is set; (c) at ingest time, attach a sentinel tag whenever the field is set, then search by that tag.\n- **Newest / largest N** — keep the filter in `expression` and sort explicitly: `sort_by: [{uploaded_at: \"desc\"}]` with `max_results: 10`.\n- **Filter by folder** — both `asset_folder:\"parent/child\"` and `folder:\"parent/child\"` match an exact folder path; there is no wildcard or \"contains\". To query across multiple folders, enumerate: `asset_folder:(\"campaigns/2024\" OR \"campaigns/2025\")`.\n- **Filter by metadata when you only know the label** — first call `list-metadata-fields` to resolve the label to an `external_id`, then query `metadata.<external_id>:value`.\n- **Multiple independent filters in one turn** — prefer one `expression` with `OR` / parentheses over firing many parallel calls: `metadata.region:apac OR metadata.region:emea` in a single request is faster and more reliable than two parallel requests.\n\n## Examples\n\n- `tags:shirt AND uploaded_at>1d`\n- `resource_type:image AND bytes>1000000 AND (format:png OR format:jpg)`\n- `folder:products AND context.category:electronics`\n- `tags:\"service:mantels\" AND -tags:discontinued`\n"
|
|
74284
74169
|
},
|
|
74285
74170
|
{
|
|
74286
74171
|
name: "visual-search-assets",
|
|
@@ -74336,8 +74221,13 @@ This tool creates actual derived assets on Cloudinary using the explicit API.`
|
|
|
74336
74221
|
|
|
74337
74222
|
// src/landing-page.ts
|
|
74338
74223
|
function landingPageExpress(req, res) {
|
|
74339
|
-
const
|
|
74340
|
-
|
|
74224
|
+
const proto = req.get("x-forwarded-proto")?.split(",")[0]?.trim() || req.protocol;
|
|
74225
|
+
const host = req.get("host");
|
|
74226
|
+
if (!host) {
|
|
74227
|
+
res.status(400).send("Missing Host header");
|
|
74228
|
+
return;
|
|
74229
|
+
}
|
|
74230
|
+
res.type("html").send(landingPageHTML(`${proto}://${host}`));
|
|
74341
74231
|
}
|
|
74342
74232
|
function landingPageHTML(origin) {
|
|
74343
74233
|
const o = origin;
|
|
@@ -75240,7 +75130,7 @@ http_headers = { "api-key" = "YOUR_API_KEY", "api-secret" = "YOUR_API_SECRET", "
|
|
|
75240
75130
|
<h1>Instructions</h1>
|
|
75241
75131
|
<p>One-click installation for Claude Desktop users</p>
|
|
75242
75132
|
<div class="instruction-item">
|
|
75243
|
-
<a href="https://github.com/cloudinary/asset-management-mcp/releases/download/v0.9.
|
|
75133
|
+
<a href="https://github.com/cloudinary/asset-management-mcp/releases/download/v0.9.2/mcp-server.mcpb" download="mcp-server.mcpb" class="action-button header-action" style="display: inline-flex; margin-bottom: 16px;">
|
|
75244
75134
|
\uD83D\uDCE5 Download MCP Bundle
|
|
75245
75135
|
</a>
|
|
75246
75136
|
</div>
|
|
@@ -75402,7 +75292,7 @@ async function startStreamableHTTP(cliFlags) {
|
|
|
75402
75292
|
app.use((req, res, next) => {
|
|
75403
75293
|
res.header("Access-Control-Allow-Origin", "*");
|
|
75404
75294
|
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
75405
|
-
res.header("Access-Control-Allow-Headers", "
|
|
75295
|
+
res.header("Access-Control-Allow-Headers", "*");
|
|
75406
75296
|
if (req.method === "OPTIONS") {
|
|
75407
75297
|
res.sendStatus(204);
|
|
75408
75298
|
return;
|
|
@@ -77184,7 +77074,7 @@ var routes = ln({
|
|
|
77184
77074
|
var app = _e(routes, {
|
|
77185
77075
|
name: "mcp",
|
|
77186
77076
|
versionInfo: {
|
|
77187
|
-
currentVersion: "0.9.
|
|
77077
|
+
currentVersion: "0.9.2"
|
|
77188
77078
|
}
|
|
77189
77079
|
});
|
|
77190
77080
|
Yt(app, process4.argv.slice(2), buildContext(process4));
|
|
@@ -77192,5 +77082,5 @@ export {
|
|
|
77192
77082
|
app
|
|
77193
77083
|
};
|
|
77194
77084
|
|
|
77195
|
-
//# debugId=
|
|
77085
|
+
//# debugId=80B49656B4FCF52064756E2164756E21
|
|
77196
77086
|
//# sourceMappingURL=mcp-server.js.map
|