@ampless/mcp-server 1.0.0-beta.59 → 1.0.0-beta.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +53 -17
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -264,7 +264,8 @@ var createPostSchema = {
|
|
|
264
264
|
description: "tiptap = rich text JSON tree; markdown = source string (GFM extensions enabled); html = raw HTML string (rendered verbatim, no sanitization)."
|
|
265
265
|
},
|
|
266
266
|
body: {
|
|
267
|
-
|
|
267
|
+
type: ["object", "array", "string"],
|
|
268
|
+
description: "tiptap JSON (when format=tiptap; pass a JSON object/array, NOT a stringified string), markdown source string (format=markdown), or raw HTML string (format=html)."
|
|
268
269
|
},
|
|
269
270
|
status: { type: "string", enum: ["draft", "published"], default: "draft" },
|
|
270
271
|
excerpt: { type: "string" },
|
|
@@ -338,7 +339,10 @@ var updatePostSchema = {
|
|
|
338
339
|
enum: ["tiptap", "markdown", "html"],
|
|
339
340
|
description: "tiptap = rich text JSON tree; markdown = source string; html = raw HTML string (no sanitization)."
|
|
340
341
|
},
|
|
341
|
-
body: {
|
|
342
|
+
body: {
|
|
343
|
+
type: ["object", "array", "string"],
|
|
344
|
+
description: "tiptap JSON (when format=tiptap; pass a JSON object/array, NOT a stringified string), markdown source, or raw HTML string"
|
|
345
|
+
},
|
|
342
346
|
status: { type: "string", enum: ["draft", "published"] },
|
|
343
347
|
publishedAt: { type: "string", description: "ISO 8601 timestamp" },
|
|
344
348
|
tags: { type: "array", items: { type: "string" } },
|
|
@@ -452,7 +456,23 @@ var uploadMediaSchema = {
|
|
|
452
456
|
}
|
|
453
457
|
}
|
|
454
458
|
};
|
|
459
|
+
var MIME_TYPE_RE = /^[a-z0-9][a-z0-9!#$&^_.+-]{0,126}\/[a-z0-9][a-z0-9!#$&^_.+-]{0,126}$/i;
|
|
460
|
+
var BLOCKED_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
461
|
+
"text/html",
|
|
462
|
+
"application/xhtml+xml",
|
|
463
|
+
"application/javascript",
|
|
464
|
+
"text/javascript"
|
|
465
|
+
]);
|
|
466
|
+
function assertSafeMimeType(mimeType) {
|
|
467
|
+
if (!MIME_TYPE_RE.test(mimeType)) {
|
|
468
|
+
throw new Error(`upload_media: invalid mimeType: ${JSON.stringify(mimeType)}`);
|
|
469
|
+
}
|
|
470
|
+
if (BLOCKED_MIME_TYPES.has(mimeType.toLowerCase())) {
|
|
471
|
+
throw new Error(`upload_media: mimeType not allowed for public media: ${mimeType}`);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
455
474
|
async function uploadMedia(graphql, storage, args) {
|
|
475
|
+
assertSafeMimeType(args.mimeType);
|
|
456
476
|
const body = Buffer.from(args.base64Data, "base64");
|
|
457
477
|
const key = buildMediaKey(args.filename);
|
|
458
478
|
const putResult = await storage.putObject(key, body, args.mimeType);
|
|
@@ -645,13 +665,16 @@ var GET_BY_ID2 = (
|
|
|
645
665
|
}
|
|
646
666
|
`
|
|
647
667
|
);
|
|
648
|
-
var
|
|
668
|
+
var FIND_BY_SRC = (
|
|
649
669
|
/* GraphQL */
|
|
650
670
|
`
|
|
651
|
-
query
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
671
|
+
query FindMediaBySrc($filter: ModelMediaFilterInput!, $nextToken: String) {
|
|
672
|
+
listMedia(filter: $filter, limit: 100, nextToken: $nextToken) {
|
|
673
|
+
items {
|
|
674
|
+
mediaId
|
|
675
|
+
src
|
|
676
|
+
}
|
|
677
|
+
nextToken
|
|
655
678
|
}
|
|
656
679
|
}
|
|
657
680
|
`
|
|
@@ -720,12 +743,18 @@ async function deleteMedia(graphql, storage, args) {
|
|
|
720
743
|
assertMediaPrefix(src);
|
|
721
744
|
}
|
|
722
745
|
} else {
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
746
|
+
let cursor;
|
|
747
|
+
do {
|
|
748
|
+
const data = await graphql.query(FIND_BY_SRC, { filter: { src: { eq: args.src } }, nextToken: cursor });
|
|
749
|
+
const row = data.listMedia.items[0];
|
|
750
|
+
if (row) {
|
|
751
|
+
mediaId = row.mediaId;
|
|
752
|
+
src = row.src;
|
|
753
|
+
assertMediaPrefix(src);
|
|
754
|
+
break;
|
|
755
|
+
}
|
|
756
|
+
cursor = data.listMedia.nextToken ?? void 0;
|
|
757
|
+
} while (cursor);
|
|
729
758
|
}
|
|
730
759
|
if (!mediaId) {
|
|
731
760
|
if (args.src) {
|
|
@@ -782,7 +811,12 @@ function getSchema() {
|
|
|
782
811
|
slug: { type: "string", required: true, description: "URL slug, unique" },
|
|
783
812
|
title: { type: "string", required: true },
|
|
784
813
|
excerpt: { type: "string" },
|
|
785
|
-
format: {
|
|
814
|
+
format: {
|
|
815
|
+
type: "enum",
|
|
816
|
+
values: ["tiptap", "markdown", "html", "static"],
|
|
817
|
+
required: true,
|
|
818
|
+
description: "`static` is read-only here \u2014 get_post / list_posts can return it, but it is created/edited only via the static-bundle tools (upload_static_bundle, upload_static_file, delete_static_file, commit_static_post), NOT create_post / update_post. See notes.staticFormat."
|
|
819
|
+
},
|
|
786
820
|
body: {
|
|
787
821
|
type: "json",
|
|
788
822
|
description: "tiptap node JSON when format=tiptap; markdown source string when format=markdown; raw HTML string when format=html"
|
|
@@ -821,7 +855,7 @@ function getSchema() {
|
|
|
821
855
|
}
|
|
822
856
|
}
|
|
823
857
|
],
|
|
824
|
-
formats: ["tiptap", "markdown", "html"],
|
|
858
|
+
formats: ["tiptap", "markdown", "html", "static"],
|
|
825
859
|
notes: {
|
|
826
860
|
editorTrust: 'editor stores arbitrary HTML/JS verbatim \u2014 same trust shape as WordPress unfiltered_html capability. See docs/architecture/04-access-layer-mcp.md \xA7"editor \u306E\u4FE1\u983C\u30E2\u30C7\u30EB".',
|
|
827
861
|
tiptapBody: 'When format=tiptap, body is the tiptap document JSON: { type: "doc", content: [...] }. The renderer expects this shape.',
|
|
@@ -1493,8 +1527,10 @@ async function uploadStaticBundle(graphql, storage, args) {
|
|
|
1493
1527
|
}
|
|
1494
1528
|
const prefix = bundlePrefix(slug);
|
|
1495
1529
|
const existing = await storage.listObjects(prefix).catch((err2) => {
|
|
1496
|
-
console.error("[upload_static_bundle] listObjects failed
|
|
1497
|
-
|
|
1530
|
+
console.error("[upload_static_bundle] listObjects failed", err2);
|
|
1531
|
+
throw new Error(
|
|
1532
|
+
`upload_static_bundle: failed to list existing bundle objects for full-prefix wipe: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
1533
|
+
);
|
|
1498
1534
|
});
|
|
1499
1535
|
for (const obj of existing) {
|
|
1500
1536
|
await storage.deleteObject(obj.key);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ampless/mcp-server",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.61",
|
|
4
4
|
"description": "MCP tool registry shared by @ampless/backend mcp-handler Lambda. Installed transitively via @ampless/admin / @ampless/backend; no direct install needed.",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"bugs": "https://github.com/heavymoons/ampless/issues",
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"fflate": "^0.8.3",
|
|
29
|
-
"ampless": "1.0.0-beta.
|
|
29
|
+
"ampless": "1.0.0-beta.54"
|
|
30
30
|
},
|
|
31
31
|
"keywords": [
|
|
32
32
|
"ampless",
|