@cloudinary/asset-management-mcp 0.9.1 → 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 +12 -15
- package/bin/mcp-server.js +288 -369
- package/bin/mcp-server.js.map +13 -13
- 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 +3 -3
- package/esm/lib/config.js +3 -3
- package/esm/mcp-server/apps/app-shared.d.ts +6 -5
- package/esm/mcp-server/apps/app-shared.d.ts.map +1 -1
- package/esm/mcp-server/apps/app-shared.js +134 -14
- 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 +99 -306
- 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/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/landing-page.ts +9 -3
- package/src/lib/config.ts +3 -3
- package/src/mcp-server/apps/app-shared.ts +135 -14
- package/src/mcp-server/apps/asset-details-app.ts +7 -13
- package/src/mcp-server/apps/asset-gallery-app.ts +99 -305
- 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/types/bigint.ts +18 -17
|
@@ -18,6 +18,7 @@ import { toJSONSchema } from "zod";
|
|
|
18
18
|
import {
|
|
19
19
|
SHARED_CSS_TOKENS,
|
|
20
20
|
SHARED_CSS_COMPONENTS,
|
|
21
|
+
SHARED_JS_ICONS,
|
|
21
22
|
SHARED_JS_MCP_CLIENT,
|
|
22
23
|
SHARED_JS_HELPERS,
|
|
23
24
|
SHARED_JS_TOOLTIPS,
|
|
@@ -61,15 +62,8 @@ const UPLOAD_CSS = /* css */ `
|
|
|
61
62
|
.upload-header h1 {
|
|
62
63
|
font-size: var(--cld-font-sm); font-weight: 600; color: var(--cld-text);
|
|
63
64
|
}
|
|
64
|
-
.upload-header-icon {
|
|
65
|
-
.upload-header {
|
|
66
|
-
.back-link {
|
|
67
|
-
position: absolute; top: -2px; right: 0;
|
|
68
|
-
background: none; border: none; cursor: pointer;
|
|
69
|
-
color: var(--cld-accent); font-size: var(--cld-font-xs);
|
|
70
|
-
padding: 2px 6px; border-radius: 4px;
|
|
71
|
-
}
|
|
72
|
-
.back-link:hover { text-decoration: underline; background: var(--cld-accent-bg); }
|
|
65
|
+
.upload-header-icon { display: flex; align-items: center; justify-content: center; }
|
|
66
|
+
.upload-header-icon svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
|
|
73
67
|
|
|
74
68
|
.upload-result .detail-section { padding: 14px 16px; }
|
|
75
69
|
.upload-result .detail-section:first-child { padding-top: 0; }
|
|
@@ -508,16 +502,18 @@ function renderPicker() {
|
|
|
508
502
|
var h = "";
|
|
509
503
|
|
|
510
504
|
h += '<div class="upload-header">';
|
|
505
|
+
h += '<span class="upload-header-icon icon-accent">' + IC.uploadCloud + '</span>';
|
|
506
|
+
h += "<h1>Upload to Cloudinary</h1>";
|
|
507
|
+
h += '<div id="header-actions" style="display:flex;align-items:center;gap:6px;margin-left:auto">';
|
|
511
508
|
if (lastResult) {
|
|
512
|
-
h += '<button class="
|
|
509
|
+
h += '<button class="icon-btn" id="back-to-result-btn">' + IC.chevronLeft + ' Back</button>';
|
|
513
510
|
}
|
|
514
|
-
h += '
|
|
515
|
-
h += "<h1>Upload to Cloudinary</h1>";
|
|
511
|
+
h += '</div>';
|
|
516
512
|
h += "</div>";
|
|
517
513
|
|
|
518
514
|
if (stagedFile) {
|
|
519
515
|
h += '<div class="upload-staged">';
|
|
520
|
-
h += '<div class="upload-staged-icon"
|
|
516
|
+
h += '<div class="upload-staged-icon">' + IC.file + '</div>';
|
|
521
517
|
h += '<div class="upload-staged-info">';
|
|
522
518
|
h += '<div class="upload-staged-name">' + esc(stagedFile.name) + "</div>";
|
|
523
519
|
if (stagedFile.size) {
|
|
@@ -528,11 +524,11 @@ function renderPicker() {
|
|
|
528
524
|
h += '<div class="upload-staged-meta">Remote URL</div>';
|
|
529
525
|
}
|
|
530
526
|
h += "</div>";
|
|
531
|
-
h += '<button class="upload-staged-clear" id="clear-staged-btn" title="Remove"
|
|
527
|
+
h += '<button class="upload-staged-clear icon-btn icon-only" id="clear-staged-btn" title="Remove">' + IC.x + '</button>';
|
|
532
528
|
h += "</div>";
|
|
533
529
|
} else {
|
|
534
530
|
h += '<div class="upload-zone" id="drop-zone">';
|
|
535
|
-
h += '<div class="upload-zone-icon"
|
|
531
|
+
h += '<div class="upload-zone-icon">' + IC.folderOpen + '</div>';
|
|
536
532
|
h += '<div class="upload-zone-text">Drag & drop a file here</div>';
|
|
537
533
|
h += '<div class="upload-zone-hint">Images, videos, PDFs, and other files up to 60 MB</div>';
|
|
538
534
|
h += '<button class="upload-zone-btn" id="browse-btn">Browse Files</button>';
|
|
@@ -556,6 +552,7 @@ function renderPicker() {
|
|
|
556
552
|
}
|
|
557
553
|
|
|
558
554
|
root.innerHTML = h;
|
|
555
|
+
renderThemeToggle();
|
|
559
556
|
|
|
560
557
|
var backBtn = document.getElementById("back-to-result-btn");
|
|
561
558
|
if (backBtn && lastResult) {
|
|
@@ -635,12 +632,13 @@ function renderUploading(name, meta) {
|
|
|
635
632
|
var h = "";
|
|
636
633
|
|
|
637
634
|
h += '<div class="upload-header">';
|
|
638
|
-
h += '<span class="upload-header-icon"
|
|
639
|
-
h +=
|
|
635
|
+
h += '<span class="upload-header-icon icon-accent">' + IC.uploadCloud + '</span>';
|
|
636
|
+
h += '<h1>Uploading…</h1>';
|
|
637
|
+
h += '<div id="header-actions" style="display:flex;align-items:center;gap:6px;margin-left:auto"></div>';
|
|
640
638
|
h += "</div>";
|
|
641
639
|
|
|
642
640
|
h += '<div class="upload-preview">';
|
|
643
|
-
h += '<div class="upload-preview-icon"
|
|
641
|
+
h += '<div class="upload-preview-icon">' + IC.file + '</div>';
|
|
644
642
|
h += '<div class="upload-preview-info">';
|
|
645
643
|
h += '<div class="upload-preview-name">' + esc(name) + "</div>";
|
|
646
644
|
h += '<div class="upload-preview-meta">' + esc(meta) + "</div>";
|
|
@@ -652,6 +650,7 @@ function renderUploading(name, meta) {
|
|
|
652
650
|
h += "</div>";
|
|
653
651
|
|
|
654
652
|
root.innerHTML = h;
|
|
653
|
+
renderThemeToggle();
|
|
655
654
|
animateProgress();
|
|
656
655
|
}
|
|
657
656
|
|
|
@@ -705,7 +704,7 @@ function renderUploadError(title, msg) {
|
|
|
705
704
|
var header = document.querySelector(".upload-header h1");
|
|
706
705
|
if (header) header.textContent = title;
|
|
707
706
|
var icon = document.querySelector(".upload-header-icon");
|
|
708
|
-
if (icon) icon.
|
|
707
|
+
if (icon) { icon.innerHTML = IC.alertTriangle; icon.className = "upload-header-icon icon-warning"; }
|
|
709
708
|
|
|
710
709
|
var safeMsg = esc(msg).replace(/\\n/g, "<br>");
|
|
711
710
|
var h = '<div class="upload-error-msg">' + safeMsg + "</div>";
|
|
@@ -717,14 +716,16 @@ function renderUploadError(title, msg) {
|
|
|
717
716
|
var root = document.getElementById("app");
|
|
718
717
|
var safeMsg = esc(msg).replace(/\\n/g, "<br>");
|
|
719
718
|
var h = '<div class="upload-header">';
|
|
720
|
-
h += '<span class="upload-header-icon"
|
|
719
|
+
h += '<span class="upload-header-icon icon-warning">' + IC.alertTriangle + '</span>';
|
|
721
720
|
h += "<h1>" + esc(title) + "</h1>";
|
|
721
|
+
h += '<div id="header-actions" style="display:flex;align-items:center;gap:6px;margin-left:auto"></div>';
|
|
722
722
|
h += "</div>";
|
|
723
723
|
h += '<div class="upload-error-msg">' + safeMsg + "</div>";
|
|
724
724
|
h += '<div class="upload-another" style="margin-top:14px;text-align:center">';
|
|
725
725
|
h += '<button class="prompt-btn prompt-btn-primary" id="retry-upload-btn">Try from App</button>';
|
|
726
726
|
h += "</div>";
|
|
727
727
|
root.innerHTML = h;
|
|
728
|
+
renderThemeToggle();
|
|
728
729
|
}
|
|
729
730
|
|
|
730
731
|
var btn = document.getElementById("retry-upload-btn");
|
|
@@ -769,8 +770,9 @@ function renderLocalFileNeeded(expectedName, errMsg) {
|
|
|
769
770
|
var classified = classifyFileError(errMsg);
|
|
770
771
|
var root = document.getElementById("app");
|
|
771
772
|
var h = '<div class="upload-header">';
|
|
772
|
-
h += '<span class="upload-header-icon"
|
|
773
|
+
h += '<span class="upload-header-icon icon-accent">' + IC.folderOpen + '</span>';
|
|
773
774
|
h += "<h1>" + esc(classified.title) + "</h1>";
|
|
775
|
+
h += '<div id="header-actions" style="display:flex;align-items:center;gap:6px;margin-left:auto"></div>';
|
|
774
776
|
h += "</div>";
|
|
775
777
|
h += '<div class="prompt" style="margin-bottom:16px">';
|
|
776
778
|
h += '<div class="prompt-desc">The file <strong>' + esc(expectedName)
|
|
@@ -785,13 +787,14 @@ function renderLocalFileNeeded(expectedName, errMsg) {
|
|
|
785
787
|
}
|
|
786
788
|
h += "</div>";
|
|
787
789
|
h += '<div class="upload-zone" id="drop-zone">';
|
|
788
|
-
h += '<div class="upload-zone-icon"
|
|
790
|
+
h += '<div class="upload-zone-icon">' + IC.folderOpen + '</div>';
|
|
789
791
|
h += '<div class="upload-zone-text">Drop <strong>' + esc(expectedName) + "</strong> here</div>";
|
|
790
792
|
h += '<div class="upload-zone-hint">Or click to browse your files</div>';
|
|
791
793
|
h += '<button class="upload-zone-btn" id="browse-btn">Browse Files</button>';
|
|
792
794
|
h += '<input type="file" id="file-input" style="display:none">';
|
|
793
795
|
h += "</div>";
|
|
794
796
|
root.innerHTML = h;
|
|
797
|
+
renderThemeToggle();
|
|
795
798
|
|
|
796
799
|
function onFileSelected(file) {
|
|
797
800
|
var reader = new FileReader();
|
|
@@ -904,8 +907,9 @@ function renderResult(r) {
|
|
|
904
907
|
var h = "";
|
|
905
908
|
|
|
906
909
|
h += '<div class="upload-header">';
|
|
907
|
-
h += '<span class="upload-header-icon
|
|
910
|
+
h += '<span class="upload-header-icon ' + (isPending ? "icon-accent" : "icon-success") + '">' + (isPending ? IC.clock : IC.checkCircle) + '</span>';
|
|
908
911
|
h += "<h1>" + (isPending ? "Upload Queued" : "Upload Complete") + "</h1>";
|
|
912
|
+
h += '<div id="header-actions" style="display:flex;align-items:center;gap:6px;margin-left:auto"></div>';
|
|
909
913
|
h += "</div>";
|
|
910
914
|
|
|
911
915
|
h += '<div class="upload-result">';
|
|
@@ -966,6 +970,7 @@ function renderResult(r) {
|
|
|
966
970
|
h += "</div></div>";
|
|
967
971
|
|
|
968
972
|
root.innerHTML = h;
|
|
973
|
+
renderThemeToggle();
|
|
969
974
|
|
|
970
975
|
root.addEventListener("click", function handler(e) {
|
|
971
976
|
var el = e.target;
|
|
@@ -1102,6 +1107,7 @@ ${UPLOAD_CSS}
|
|
|
1102
1107
|
<div id="app"><div class="status">Preparing upload…</div></div>
|
|
1103
1108
|
|
|
1104
1109
|
<script>
|
|
1110
|
+
${SHARED_JS_ICONS}
|
|
1105
1111
|
${SHARED_JS_MCP_CLIENT}
|
|
1106
1112
|
${SHARED_JS_HELPERS}
|
|
1107
1113
|
${SHARED_JS_TOOLTIPS}
|
|
@@ -12,8 +12,7 @@ export const MCP_APPS: readonly McpApp[] = [
|
|
|
12
12
|
"asset-upload",
|
|
13
13
|
];
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
export const DEFAULT_MCP_APPS: readonly McpApp[] = [];
|
|
15
|
+
export const DEFAULT_MCP_APPS: readonly McpApp[] = [...MCP_APPS];
|
|
17
16
|
|
|
18
17
|
export function parseMcpAppsList(value: string): McpApp[] {
|
|
19
18
|
const parts = value.split(",").map((s) => s.trim()).filter(Boolean);
|
|
@@ -66,7 +66,12 @@ function appResourceContent(uri: URL, html: string) {
|
|
|
66
66
|
uri: uri.toString(),
|
|
67
67
|
mimeType: MCP_APP_MIME_TYPE,
|
|
68
68
|
text: html,
|
|
69
|
-
_meta: {
|
|
69
|
+
_meta: {
|
|
70
|
+
ui: {
|
|
71
|
+
csp: { resourceDomains: CSP_RESOURCE_DOMAINS },
|
|
72
|
+
permissions: { clipboardWrite: {} },
|
|
73
|
+
},
|
|
74
|
+
},
|
|
70
75
|
// deno-lint-ignore no-explicit-any
|
|
71
76
|
} as any],
|
|
72
77
|
};
|
|
@@ -42,7 +42,7 @@ async function startStreamableHTTP(cliFlags: ServeCommandFlags) {
|
|
|
42
42
|
app.use((req, res, next) => {
|
|
43
43
|
res.header("Access-Control-Allow-Origin", "*");
|
|
44
44
|
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
45
|
-
res.header("Access-Control-Allow-Headers", "
|
|
45
|
+
res.header("Access-Control-Allow-Headers", "*");
|
|
46
46
|
if (req.method === "OPTIONS") {
|
|
47
47
|
res.sendStatus(204);
|
|
48
48
|
return;
|
package/src/mcp-server/server.ts
CHANGED
package/src/types/bigint.ts
CHANGED
|
@@ -25,23 +25,24 @@ export function bigint(): z.ZodType<bigint | string> {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export function bigintOptional(): z.ZodType<bigint | string | undefined> {
|
|
28
|
-
return z
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
28
|
+
return z
|
|
29
|
+
.union([
|
|
30
|
+
z.bigint().transform((v) => String(v)),
|
|
31
|
+
z.string().transform((v, ctx) => {
|
|
32
|
+
try {
|
|
33
|
+
return BigInt(v);
|
|
34
|
+
} catch {
|
|
35
|
+
ctx.addIssue({
|
|
36
|
+
code: z.ZodIssueCode.custom,
|
|
37
|
+
message: "Invalid bigint value",
|
|
38
|
+
});
|
|
39
|
+
return z.NEVER;
|
|
40
|
+
}
|
|
41
|
+
}),
|
|
42
|
+
z.number().transform((v) => BigInt(Math.trunc(v))),
|
|
43
|
+
z.null().transform(() => undefined),
|
|
44
|
+
])
|
|
45
|
+
.optional();
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
export function bigintNullable(): z.ZodType<bigint | string | null> {
|