brewpage-mcp 1.1.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +74 -17
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -34,7 +34,7 @@ function formatPublishResponse(data) {
|
|
|
34
34
|
lines.push(``, `===================================`, `OWNER TOKEN: ${data.ownerToken}`, `===================================`, ``, `IMPORTANT: Save your owner token! You need it to update or delete this resource later. It cannot be recovered if lost.`);
|
|
35
35
|
return lines.join("\n");
|
|
36
36
|
}
|
|
37
|
-
server.tool("publish_html", "Publish HTML or Markdown content to BrewPage. Returns a public URL and owner token. Supports password protection and
|
|
37
|
+
server.tool("publish_html", "Publish HTML or Markdown content to BrewPage. Returns a public URL and owner token. Supports password protection, custom TTL, optional filename, and an opt-in top toolbar (showTopBar).", {
|
|
38
38
|
content: z.string().describe("HTML or Markdown content to publish"),
|
|
39
39
|
format: z
|
|
40
40
|
.enum(["HTML", "MARKDOWN"])
|
|
@@ -50,11 +50,21 @@ server.tool("publish_html", "Publish HTML or Markdown content to BrewPage. Retur
|
|
|
50
50
|
.describe("Optional password to protect the page"),
|
|
51
51
|
ttlDays: z
|
|
52
52
|
.number()
|
|
53
|
-
.
|
|
54
|
-
.
|
|
53
|
+
.int()
|
|
54
|
+
.min(1)
|
|
55
|
+
.max(30)
|
|
56
|
+
.optional()
|
|
57
|
+
.describe("Time to live in days (1-30, default: 15)"),
|
|
58
|
+
filename: z
|
|
59
|
+
.string()
|
|
60
|
+
.max(200)
|
|
55
61
|
.optional()
|
|
56
|
-
.describe("
|
|
57
|
-
|
|
62
|
+
.describe("Optional original filename (≤200 chars). Used as title fallback when no <title>/<h1>; immutable on update."),
|
|
63
|
+
showTopBar: z
|
|
64
|
+
.boolean()
|
|
65
|
+
.optional()
|
|
66
|
+
.describe("Add a thin top toolbar (filename + Download button + theme toggle) on the served page. Default: hidden."),
|
|
67
|
+
}, async ({ content, format, namespace, password, ttlDays, filename, showTopBar }) => {
|
|
58
68
|
const body = { content, format };
|
|
59
69
|
if (namespace)
|
|
60
70
|
body.namespace = namespace;
|
|
@@ -62,6 +72,10 @@ server.tool("publish_html", "Publish HTML or Markdown content to BrewPage. Retur
|
|
|
62
72
|
body.password = password;
|
|
63
73
|
if (ttlDays)
|
|
64
74
|
body.ttlDays = ttlDays;
|
|
75
|
+
if (filename)
|
|
76
|
+
body.filename = filename;
|
|
77
|
+
if (showTopBar !== undefined)
|
|
78
|
+
body.showTopBar = showTopBar;
|
|
65
79
|
const { ok, data } = await apiRequest("POST", "/api/html", body);
|
|
66
80
|
if (!ok) {
|
|
67
81
|
return {
|
|
@@ -229,8 +243,19 @@ server.tool("get_stats", "Get BrewPage platform-wide usage statistics including
|
|
|
229
243
|
],
|
|
230
244
|
};
|
|
231
245
|
});
|
|
232
|
-
server.tool("publish_site", "Publish
|
|
233
|
-
entryContent: z
|
|
246
|
+
server.tool("publish_site", "Publish an HTML site to BrewPage. Single-page: pass `entryContent`. Multi-page: pass `files` (array of `{path, content}`). Optional `entry` overrides default `index.html`.", {
|
|
247
|
+
entryContent: z
|
|
248
|
+
.string()
|
|
249
|
+
.optional()
|
|
250
|
+
.describe("HTML content for a single-page site (entry file). Mutually exclusive with `files`."),
|
|
251
|
+
files: z
|
|
252
|
+
.array(z.object({ path: z.string(), content: z.string() }))
|
|
253
|
+
.optional()
|
|
254
|
+
.describe("Multi-file site: array of `{path, content}`. Mutually exclusive with `entryContent`."),
|
|
255
|
+
entry: z
|
|
256
|
+
.string()
|
|
257
|
+
.optional()
|
|
258
|
+
.describe("Entry file path, default index.html"),
|
|
234
259
|
namespace: z
|
|
235
260
|
.string()
|
|
236
261
|
.optional()
|
|
@@ -244,26 +269,52 @@ server.tool("publish_site", "Publish a single-page HTML site to BrewPage. Accept
|
|
|
244
269
|
.min(1)
|
|
245
270
|
.max(30)
|
|
246
271
|
.optional()
|
|
247
|
-
.describe("Time to live in days (1-30, default:
|
|
272
|
+
.describe("Time to live in days (1-30, default: 15)"),
|
|
248
273
|
ownerToken: z
|
|
249
274
|
.string()
|
|
250
275
|
.optional()
|
|
251
276
|
.describe("Existing owner token to group this site under the same owner as previous content"),
|
|
252
|
-
}, async ({ entryContent, namespace, password, ttlDays, ownerToken }) => {
|
|
277
|
+
}, async ({ entryContent, files, entry, namespace, password, ttlDays, ownerToken }) => {
|
|
278
|
+
const hasEntry = typeof entryContent === "string";
|
|
279
|
+
const hasFiles = Array.isArray(files) && files.length > 0;
|
|
280
|
+
if (hasEntry === hasFiles) {
|
|
281
|
+
return {
|
|
282
|
+
content: [
|
|
283
|
+
{
|
|
284
|
+
type: "text",
|
|
285
|
+
text: "Provide exactly one of `entryContent` (single-page) or `files` (multi-page).",
|
|
286
|
+
},
|
|
287
|
+
],
|
|
288
|
+
isError: true,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
253
291
|
const formData = new FormData();
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
292
|
+
if (hasFiles) {
|
|
293
|
+
for (const f of files) {
|
|
294
|
+
formData.append("files", new Blob([f.content], { type: "text/html" }), f.path);
|
|
295
|
+
formData.append("paths", f.path);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
const entryBlob = new Blob([entryContent], { type: "text/html" });
|
|
300
|
+
const entryName = entry || "index.html";
|
|
301
|
+
formData.append("files", entryBlob, entryName);
|
|
302
|
+
formData.append("paths", entryName);
|
|
303
|
+
}
|
|
261
304
|
const headers = {};
|
|
262
305
|
if (password)
|
|
263
306
|
headers["X-Password"] = password;
|
|
264
307
|
if (ownerToken)
|
|
265
308
|
headers["X-Owner-Token"] = ownerToken;
|
|
266
|
-
const
|
|
309
|
+
const qsParams = [];
|
|
310
|
+
if (entry)
|
|
311
|
+
qsParams.push(`entry=${encodeURIComponent(entry)}`);
|
|
312
|
+
if (namespace)
|
|
313
|
+
qsParams.push(`ns=${encodeURIComponent(namespace)}`);
|
|
314
|
+
if (ttlDays)
|
|
315
|
+
qsParams.push(`ttl=${encodeURIComponent(String(ttlDays))}`);
|
|
316
|
+
const qs = qsParams.length ? `?${qsParams.join("&")}` : "";
|
|
317
|
+
const url = `${BASE_URL}/api/sites${qs}`;
|
|
267
318
|
const res = await fetch(url, { method: "POST", headers, body: formData });
|
|
268
319
|
const data = await res.json().catch(() => null);
|
|
269
320
|
if (!res.ok) {
|
|
@@ -287,6 +338,12 @@ server.tool("publish_site", "Publish a single-page HTML site to BrewPage. Accept
|
|
|
287
338
|
`Entry file: ${site.entryFile || "index.html"}`,
|
|
288
339
|
`Files: ${site.fileCount || 1}`,
|
|
289
340
|
];
|
|
341
|
+
if (site.totalSizeBytes !== undefined)
|
|
342
|
+
lines.push(`Size: ${site.totalSizeBytes} bytes`);
|
|
343
|
+
if (site.ownerLink)
|
|
344
|
+
lines.push(`Owner link: ${site.ownerLink}`);
|
|
345
|
+
if (Array.isArray(site.tags) && site.tags.length)
|
|
346
|
+
lines.push(`Tags: ${site.tags.join(", ")}`);
|
|
290
347
|
if (site.expiresAt)
|
|
291
348
|
lines.push(`Expires: ${site.expiresAt}`);
|
|
292
349
|
lines.push(``, `===================================`, `OWNER TOKEN: ${site.ownerToken}`, `===================================`, ``, `IMPORTANT: Save your owner token! You need it to view info or delete this site. It cannot be recovered if lost.`);
|