@cloudinary/asset-management-mcp 0.9.2 → 0.9.3
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 +2 -2
- package/bin/mcp-server.js +86 -17
- package/bin/mcp-server.js.map +8 -8
- package/esm/landing-page.js +1 -1
- package/esm/lib/config.d.ts +2 -2
- package/esm/lib/config.js +2 -2
- package/esm/mcp-server/apps/app-shared.d.ts +3 -3
- package/esm/mcp-server/apps/app-shared.d.ts.map +1 -1
- package/esm/mcp-server/apps/app-shared.js +56 -3
- package/esm/mcp-server/apps/app-shared.js.map +1 -1
- package/esm/mcp-server/apps/asset-gallery-app.js +24 -8
- package/esm/mcp-server/apps/asset-gallery-app.js.map +1 -1
- package/esm/mcp-server/mcp-server.js +1 -1
- package/esm/mcp-server/server.js +1 -1
- package/package.json +1 -1
- package/src/landing-page.ts +1 -1
- package/src/lib/config.ts +2 -2
- package/src/mcp-server/apps/app-shared.ts +56 -3
- package/src/mcp-server/apps/asset-gallery-app.ts +24 -8
- package/src/mcp-server/mcp-server.ts +1 -1
- package/src/mcp-server/server.ts +1 -1
package/README.md
CHANGED
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
<details>
|
|
31
31
|
<summary>Claude Desktop</summary>
|
|
32
32
|
|
|
33
|
-
Install the MCP server as a Desktop Extension using the pre-built [`mcp-server.mcpb`](https://github.com/cloudinary/asset-management-mcp/releases/download/v0.9.
|
|
33
|
+
Install the MCP server as a Desktop Extension using the pre-built [`mcp-server.mcpb`](https://github.com/cloudinary/asset-management-mcp/releases/download/v0.9.3/mcp-server.mcpb) file:
|
|
34
34
|
|
|
35
|
-
Simply drag and drop the [`mcp-server.mcpb`](https://github.com/cloudinary/asset-management-mcp/releases/download/v0.9.
|
|
35
|
+
Simply drag and drop the [`mcp-server.mcpb`](https://github.com/cloudinary/asset-management-mcp/releases/download/v0.9.3/mcp-server.mcpb) file onto Claude Desktop to install the extension.
|
|
36
36
|
|
|
37
37
|
The MCP bundle package includes the MCP server and all necessary configuration. Once installed, the server will be available without additional setup.
|
|
38
38
|
|
package/bin/mcp-server.js
CHANGED
|
@@ -13960,9 +13960,9 @@ var init_config = __esm(() => {
|
|
|
13960
13960
|
SDK_METADATA = {
|
|
13961
13961
|
language: "typescript",
|
|
13962
13962
|
openapiDocVersion: "0.5.1",
|
|
13963
|
-
sdkVersion: "0.9.
|
|
13963
|
+
sdkVersion: "0.9.3",
|
|
13964
13964
|
genVersion: "2.885.1",
|
|
13965
|
-
userAgent: "speakeasy-sdk/mcp-typescript 0.9.
|
|
13965
|
+
userAgent: "speakeasy-sdk/mcp-typescript 0.9.3 2.885.1 0.5.1 @cloudinary/asset-management-mcp"
|
|
13966
13966
|
};
|
|
13967
13967
|
});
|
|
13968
13968
|
|
|
@@ -65624,7 +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 {
|
|
65627
|
+
html { scrollbar-gutter: auto; }
|
|
65628
65628
|
body {
|
|
65629
65629
|
font-family: var(--cld-font);
|
|
65630
65630
|
background: var(--cld-bg);
|
|
@@ -65633,6 +65633,7 @@ body {
|
|
|
65633
65633
|
line-height: 1.5;
|
|
65634
65634
|
font-size: var(--cld-font-xs);
|
|
65635
65635
|
position: relative;
|
|
65636
|
+
overflow-x: hidden;
|
|
65636
65637
|
}
|
|
65637
65638
|
.theme-btn {
|
|
65638
65639
|
width: 22px; height: 22px; border-radius: 50%;
|
|
@@ -65668,9 +65669,11 @@ body {
|
|
|
65668
65669
|
.link { cursor: pointer; }
|
|
65669
65670
|
.link:hover { color: var(--cld-accent); text-decoration: underline; }
|
|
65670
65671
|
|
|
65671
|
-
/* Modal
|
|
65672
|
+
/* Modal — positioned absolutely so it can be placed in the part of the
|
|
65673
|
+
* iframe that is currently visible in the host's viewport (since position:fixed
|
|
65674
|
+
* inside a tall iframe anchors to iframe-center, not the user's visible area). */
|
|
65672
65675
|
.modal-overlay {
|
|
65673
|
-
position:
|
|
65676
|
+
position: absolute; left: 0; right: 0;
|
|
65674
65677
|
background: rgba(0,0,0,0.45);
|
|
65675
65678
|
display: flex; align-items: center; justify-content: center;
|
|
65676
65679
|
z-index: 1000; backdrop-filter: blur(3px); padding: 24px;
|
|
@@ -66506,6 +66509,55 @@ function closeModal() {
|
|
|
66506
66509
|
if (ov) ov.remove();
|
|
66507
66510
|
}
|
|
66508
66511
|
|
|
66512
|
+
/* Position the modal overlay so it's centered on the part of the iframe
|
|
66513
|
+
* the user is currently looking at. Inside an iframe that the host has
|
|
66514
|
+
* sized to scrollHeight, position: fixed anchors to iframe-center, not
|
|
66515
|
+
* the user's visible band — so we compute the visible band ourselves
|
|
66516
|
+
* via IntersectionObserver and place the overlay absolutely there. */
|
|
66517
|
+
function positionModalInVisibleArea(overlay) {
|
|
66518
|
+
if (!overlay) return;
|
|
66519
|
+
var docH = Math.max(document.documentElement.scrollHeight, window.innerHeight);
|
|
66520
|
+
|
|
66521
|
+
// Try IntersectionObserver first (works cross-origin too)
|
|
66522
|
+
if (typeof IntersectionObserver !== "undefined") {
|
|
66523
|
+
var probe = document.createElement("div");
|
|
66524
|
+
probe.style.cssText = "position:absolute;left:0;top:0;width:1px;height:" + docH + "px;pointer-events:none;visibility:hidden;";
|
|
66525
|
+
document.body.appendChild(probe);
|
|
66526
|
+
var io = new IntersectionObserver(function(entries) {
|
|
66527
|
+
try {
|
|
66528
|
+
var entry = entries[0];
|
|
66529
|
+
var rect = entry.intersectionRect;
|
|
66530
|
+
var rootRect = entry.rootBounds || entry.boundingClientRect;
|
|
66531
|
+
// intersectionRect.top is in viewport coords; visible band of the
|
|
66532
|
+
// document is from (probe.top + rect.top) to (probe.top + rect.bottom).
|
|
66533
|
+
var probeTop = entry.boundingClientRect.top; // viewport-relative
|
|
66534
|
+
var visibleTop = rect.top - probeTop; // document-relative
|
|
66535
|
+
var visibleHeight = rect.height;
|
|
66536
|
+
if (visibleHeight > 0) {
|
|
66537
|
+
overlay.style.top = visibleTop + "px";
|
|
66538
|
+
overlay.style.height = visibleHeight + "px";
|
|
66539
|
+
} else {
|
|
66540
|
+
// Fallback: probe not intersecting (shouldn't happen with full-height probe)
|
|
66541
|
+
overlay.style.top = (window.scrollY || 0) + "px";
|
|
66542
|
+
overlay.style.height = window.innerHeight + "px";
|
|
66543
|
+
}
|
|
66544
|
+
} finally {
|
|
66545
|
+
io.disconnect();
|
|
66546
|
+
if (probe.parentNode) probe.parentNode.removeChild(probe);
|
|
66547
|
+
}
|
|
66548
|
+
});
|
|
66549
|
+
io.observe(probe);
|
|
66550
|
+
return;
|
|
66551
|
+
}
|
|
66552
|
+
|
|
66553
|
+
// Fallback: same-origin only — read iframe's bounding rect
|
|
66554
|
+
var rect = document.documentElement.getBoundingClientRect();
|
|
66555
|
+
var visibleTop = rect.top < 0 ? -rect.top : 0;
|
|
66556
|
+
var visibleHeight = Math.min(window.innerHeight, rect.bottom) - Math.max(0, rect.top);
|
|
66557
|
+
overlay.style.top = visibleTop + "px";
|
|
66558
|
+
overlay.style.height = Math.max(visibleHeight, 200) + "px";
|
|
66559
|
+
}
|
|
66560
|
+
|
|
66509
66561
|
function openModal(headerHtml, bodyHtml) {
|
|
66510
66562
|
closeModal();
|
|
66511
66563
|
var h = '<div class="modal-overlay"><div class="modal">';
|
|
@@ -66515,6 +66567,7 @@ function openModal(headerHtml, bodyHtml) {
|
|
|
66515
66567
|
document.body.insertAdjacentHTML("beforeend", h);
|
|
66516
66568
|
|
|
66517
66569
|
var overlay = document.querySelector(".modal-overlay");
|
|
66570
|
+
positionModalInVisibleArea(overlay);
|
|
66518
66571
|
overlay.addEventListener("click", function(e) {
|
|
66519
66572
|
if (e.target === overlay || e.target.classList.contains("modal-close")) {
|
|
66520
66573
|
closeModal();
|
|
@@ -67745,17 +67798,27 @@ var GALLERY_CSS = `
|
|
|
67745
67798
|
}
|
|
67746
67799
|
|
|
67747
67800
|
/* ── Multi-select bar ── */
|
|
67801
|
+
/* Wrapper takes layout space ONLY when a selection is active. When idle
|
|
67802
|
+
* it's display:none so it contributes 0 to scrollHeight (no phantom
|
|
67803
|
+
* scrollbar gutter / no extra iframe height). */
|
|
67804
|
+
.select-bar-wrap {
|
|
67805
|
+
display: none;
|
|
67806
|
+
position: sticky; bottom: 0; left: 0; right: 0;
|
|
67807
|
+
justify-content: center; pointer-events: none;
|
|
67808
|
+
z-index: 100; height: 64px;
|
|
67809
|
+
}
|
|
67810
|
+
.select-bar-wrap.visible { display: flex; }
|
|
67748
67811
|
.select-bar {
|
|
67749
|
-
position:
|
|
67750
|
-
transform:
|
|
67812
|
+
position: absolute; bottom: 8px;
|
|
67813
|
+
transform: translateY(80px);
|
|
67751
67814
|
background: #1a1d24; color: white; border-radius: 40px;
|
|
67752
67815
|
padding: 0 6px 0 16px; height: 48px;
|
|
67753
67816
|
display: flex; align-items: center; gap: 4px;
|
|
67754
67817
|
box-shadow: 0 8px 32px rgba(0,0,0,0.4);
|
|
67755
67818
|
transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.2s;
|
|
67756
|
-
opacity: 0; pointer-events: none;
|
|
67819
|
+
opacity: 0; pointer-events: none; white-space: nowrap;
|
|
67757
67820
|
}
|
|
67758
|
-
.select-bar.visible { transform:
|
|
67821
|
+
.select-bar-wrap.visible .select-bar { transform: translateY(0); opacity: 1; pointer-events: all; }
|
|
67759
67822
|
.select-count { font-size: 13px; font-weight: 600; margin-right: 8px; }
|
|
67760
67823
|
.bar-btn {
|
|
67761
67824
|
height: 36px; padding: 0 14px; border: none; border-radius: 30px;
|
|
@@ -67818,12 +67881,12 @@ function showToast(msg) {
|
|
|
67818
67881
|
}
|
|
67819
67882
|
|
|
67820
67883
|
function updateSelectBar() {
|
|
67821
|
-
var
|
|
67884
|
+
var wrap = document.getElementById("select-bar-wrap");
|
|
67822
67885
|
var countEl = document.getElementById("select-count");
|
|
67823
|
-
if (!
|
|
67886
|
+
if (!wrap || !countEl) return;
|
|
67824
67887
|
var n = selected.size;
|
|
67825
67888
|
countEl.textContent = n + " selected";
|
|
67826
|
-
|
|
67889
|
+
wrap.classList.toggle("visible", n > 0);
|
|
67827
67890
|
var btn = document.getElementById("select-all-btn");
|
|
67828
67891
|
if (btn) {
|
|
67829
67892
|
var visible = getVisibleIndices();
|
|
@@ -68103,7 +68166,8 @@ function render() {
|
|
|
68103
68166
|
h += "</div>";
|
|
68104
68167
|
}
|
|
68105
68168
|
|
|
68106
|
-
// Multi-select bar
|
|
68169
|
+
// Multi-select bar (sticky, in-flow wrapper so iframe sizing stays truthful)
|
|
68170
|
+
h += '<div class="select-bar-wrap" id="select-bar-wrap">';
|
|
68107
68171
|
h += '<div class="select-bar" id="select-bar">';
|
|
68108
68172
|
h += '<span class="select-count" id="select-count">0 selected</span>';
|
|
68109
68173
|
h += '<div class="bar-divider"></div>';
|
|
@@ -68113,6 +68177,7 @@ function render() {
|
|
|
68113
68177
|
h += '<div class="bar-divider"></div>';
|
|
68114
68178
|
h += '<button class="bar-btn bar-ghost" id="bar-clear">' + IC.x + '</button>';
|
|
68115
68179
|
h += '</div>';
|
|
68180
|
+
h += '</div>';
|
|
68116
68181
|
|
|
68117
68182
|
// Toast
|
|
68118
68183
|
h += '<div class="gallery-toast" id="gallery-toast"></div>';
|
|
@@ -68342,6 +68407,9 @@ async function fetchDirect() {
|
|
|
68342
68407
|
console.log(LOG_PREFIX, "fetchDirect ->", name);
|
|
68343
68408
|
|
|
68344
68409
|
document.getElementById("app").innerHTML = '<div class="status">Fetching assets\\u2026</div>';
|
|
68410
|
+
requestAnimationFrame(function() {
|
|
68411
|
+
app.reportSize(Math.max(document.documentElement.scrollHeight, MIN_HEIGHT));
|
|
68412
|
+
});
|
|
68345
68413
|
try {
|
|
68346
68414
|
var res = await app.callServerTool({ name: name, arguments: args });
|
|
68347
68415
|
var data = ingestResult(res);
|
|
@@ -68393,6 +68461,7 @@ async function loadMore() {
|
|
|
68393
68461
|
function refreshGallery() {
|
|
68394
68462
|
allResources = [];
|
|
68395
68463
|
lastCursor = null;
|
|
68464
|
+
selected.clear();
|
|
68396
68465
|
fetchDirect();
|
|
68397
68466
|
}
|
|
68398
68467
|
|
|
@@ -73948,7 +74017,7 @@ A report on the status of product environment usage, including storage, credits,
|
|
|
73948
74017
|
function createMCPServer(deps) {
|
|
73949
74018
|
const server = new McpServer({
|
|
73950
74019
|
name: "CloudinaryAssetMgmt",
|
|
73951
|
-
version: "0.9.
|
|
74020
|
+
version: "0.9.3"
|
|
73952
74021
|
});
|
|
73953
74022
|
const getClient = deps.getSDK || (() => new CloudinaryAssetMgmtCore({
|
|
73954
74023
|
security: deps.security,
|
|
@@ -75130,7 +75199,7 @@ http_headers = { "api-key" = "YOUR_API_KEY", "api-secret" = "YOUR_API_SECRET", "
|
|
|
75130
75199
|
<h1>Instructions</h1>
|
|
75131
75200
|
<p>One-click installation for Claude Desktop users</p>
|
|
75132
75201
|
<div class="instruction-item">
|
|
75133
|
-
<a href="https://github.com/cloudinary/asset-management-mcp/releases/download/v0.9.
|
|
75202
|
+
<a href="https://github.com/cloudinary/asset-management-mcp/releases/download/v0.9.3/mcp-server.mcpb" download="mcp-server.mcpb" class="action-button header-action" style="display: inline-flex; margin-bottom: 16px;">
|
|
75134
75203
|
\uD83D\uDCE5 Download MCP Bundle
|
|
75135
75204
|
</a>
|
|
75136
75205
|
</div>
|
|
@@ -77074,7 +77143,7 @@ var routes = ln({
|
|
|
77074
77143
|
var app = _e(routes, {
|
|
77075
77144
|
name: "mcp",
|
|
77076
77145
|
versionInfo: {
|
|
77077
|
-
currentVersion: "0.9.
|
|
77146
|
+
currentVersion: "0.9.3"
|
|
77078
77147
|
}
|
|
77079
77148
|
});
|
|
77080
77149
|
Yt(app, process4.argv.slice(2), buildContext(process4));
|
|
@@ -77082,5 +77151,5 @@ export {
|
|
|
77082
77151
|
app
|
|
77083
77152
|
};
|
|
77084
77153
|
|
|
77085
|
-
//# debugId=
|
|
77154
|
+
//# debugId=6C5BCA15F724A25664756E2164756E21
|
|
77086
77155
|
//# sourceMappingURL=mcp-server.js.map
|