brewpage-mcp 1.0.0 → 1.1.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 +59 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -229,6 +229,65 @@ server.tool("get_stats", "Get BrewPage platform-wide usage statistics including
|
|
|
229
229
|
],
|
|
230
230
|
};
|
|
231
231
|
});
|
|
232
|
+
server.tool("publish_site", "Publish a multi-file HTML site to BrewPage. Provide HTML content as the entry file (index.html). Returns a public URL and owner token.", {
|
|
233
|
+
entryContent: z.string().describe("HTML content for the site entry file (index.html)"),
|
|
234
|
+
namespace: z
|
|
235
|
+
.string()
|
|
236
|
+
.optional()
|
|
237
|
+
.describe("Namespace for the site (optional, defaults to 'public')"),
|
|
238
|
+
password: z
|
|
239
|
+
.string()
|
|
240
|
+
.optional()
|
|
241
|
+
.describe("Optional password to protect the site"),
|
|
242
|
+
ttlDays: z
|
|
243
|
+
.number()
|
|
244
|
+
.min(1)
|
|
245
|
+
.max(30)
|
|
246
|
+
.optional()
|
|
247
|
+
.describe("Time to live in days (1-30, default: 5)"),
|
|
248
|
+
}, async ({ entryContent, namespace, password, ttlDays }) => {
|
|
249
|
+
const formData = new FormData();
|
|
250
|
+
const entryBlob = new Blob([entryContent], { type: "text/html" });
|
|
251
|
+
formData.append("files", entryBlob, "index.html");
|
|
252
|
+
formData.append("paths", "index.html");
|
|
253
|
+
if (namespace)
|
|
254
|
+
formData.append("ns", namespace);
|
|
255
|
+
if (ttlDays)
|
|
256
|
+
formData.append("ttl", String(ttlDays));
|
|
257
|
+
const headers = {};
|
|
258
|
+
if (password)
|
|
259
|
+
headers["X-Password"] = password;
|
|
260
|
+
const url = `${BASE_URL}/api/sites`;
|
|
261
|
+
const res = await fetch(url, { method: "POST", headers, body: formData });
|
|
262
|
+
const data = await res.json().catch(() => null);
|
|
263
|
+
if (!res.ok) {
|
|
264
|
+
return {
|
|
265
|
+
content: [
|
|
266
|
+
{
|
|
267
|
+
type: "text",
|
|
268
|
+
text: `Failed to publish site: ${JSON.stringify(data)}`,
|
|
269
|
+
},
|
|
270
|
+
],
|
|
271
|
+
isError: true,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
const site = data;
|
|
275
|
+
const lines = [
|
|
276
|
+
`Site published successfully!`,
|
|
277
|
+
``,
|
|
278
|
+
`URL: ${site.link || "N/A"}`,
|
|
279
|
+
`Namespace: ${site.namespace || "N/A"}`,
|
|
280
|
+
`ID: ${site.id || "N/A"}`,
|
|
281
|
+
`Entry file: ${site.entryFile || "index.html"}`,
|
|
282
|
+
`Files: ${site.fileCount || 1}`,
|
|
283
|
+
];
|
|
284
|
+
if (site.expiresAt)
|
|
285
|
+
lines.push(`Expires: ${site.expiresAt}`);
|
|
286
|
+
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.`);
|
|
287
|
+
return {
|
|
288
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
289
|
+
};
|
|
290
|
+
});
|
|
232
291
|
async function main() {
|
|
233
292
|
const transport = new StdioServerTransport();
|
|
234
293
|
await server.connect(transport);
|