brewpage-mcp 1.10.0 → 1.11.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/README.md +16 -12
- package/dist/index.js +20 -36
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ MCP server for [BrewPage](https://brewpage.app) -- publish and manage HTML, KV,
|
|
|
12
12
|
## Quick Start
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
npx -y brewpage-mcp@1.
|
|
15
|
+
npx -y brewpage-mcp@1.11.0
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
Requires Node.js 20 or newer. This starts the stdio server for an MCP client.
|
|
@@ -28,7 +28,7 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)
|
|
|
28
28
|
"mcpServers": {
|
|
29
29
|
"brewpage": {
|
|
30
30
|
"command": "npx",
|
|
31
|
-
"args": ["-y", "brewpage-mcp@1.
|
|
31
|
+
"args": ["-y", "brewpage-mcp@1.11.0"]
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -39,7 +39,7 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)
|
|
|
39
39
|
Register a project-scoped stdio server:
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
claude mcp add --transport stdio --scope project brewpage -- npx -y brewpage-mcp@1.
|
|
42
|
+
claude mcp add --transport stdio --scope project brewpage -- npx -y brewpage-mcp@1.11.0
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
This writes `.mcp.json` in the project root. Use `--scope user` for user-scoped registration. See the [official Claude Code MCP guide](https://code.claude.com/docs/en/mcp).
|
|
@@ -53,7 +53,7 @@ Open **Settings > MCP** and add:
|
|
|
53
53
|
"mcpServers": {
|
|
54
54
|
"brewpage": {
|
|
55
55
|
"command": "npx",
|
|
56
|
-
"args": ["-y", "brewpage-mcp@1.
|
|
56
|
+
"args": ["-y", "brewpage-mcp@1.11.0"]
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
}
|
|
@@ -67,7 +67,7 @@ Open the Cline MCP settings panel and add:
|
|
|
67
67
|
{
|
|
68
68
|
"brewpage": {
|
|
69
69
|
"command": "npx",
|
|
70
|
-
"args": ["-y", "brewpage-mcp@1.
|
|
70
|
+
"args": ["-y", "brewpage-mcp@1.11.0"]
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
```
|
|
@@ -75,7 +75,7 @@ Open the Cline MCP settings panel and add:
|
|
|
75
75
|
### Global Install
|
|
76
76
|
|
|
77
77
|
```bash
|
|
78
|
-
npm install -g brewpage-mcp@1.
|
|
78
|
+
npm install -g brewpage-mcp@1.11.0
|
|
79
79
|
brewpage-mcp
|
|
80
80
|
```
|
|
81
81
|
|
|
@@ -104,7 +104,7 @@ Sixteen tools are available. Creation returns an owner token; keep it to modify
|
|
|
104
104
|
|
|
105
105
|
All five publish tools accept optional `deliveryMode: "path" | "subdomain"`, sent only as `X-Delivery-Mode`; authored JSON and multipart bodies keep their existing format. Visibility and password protection are separate choices. Omitted namespace still generates an unlisted `priv-<random>` namespace; anyone with an unpassworded unlisted link can read it. `public` grants gallery/search eligibility only; password-protected content remains excluded and unlisted, protected or otherwise ineligible native responses carry `noindex`; eligible public HTML, sites and files may permit indexing.
|
|
106
106
|
|
|
107
|
-
The MCP server wraps a subset of the backend-generated public [REST contract](../openapi/openapi.json).
|
|
107
|
+
The MCP server wraps a subset of the backend-generated public [REST contract](../openapi/openapi.json). TTL inputs take days or a string such as `2w`/`36h` (default 15); the server rounds to whole days and clamps to 1–30 (owner-specific caps and eligible automatic extensions can differ). Use returned `expiresAt`. Every tolerated-input adjustment (TTL clamp, format alias, skipped site member, normalised namespace) comes back in the response `notices` array and is printed as `Notice (code): message`. `get_page` reads stored rendered HTML or format-specific code/text from the API; it does not call the owner-only original-source endpoint or a browser viewer. `publish_file` uploads from a source URL and does not expose password or TTL inputs.
|
|
108
108
|
|
|
109
109
|
For a fresh publication, sites and HTML pages of format `HTML` outside `public` (including the generated unlisted namespace) always use Dedicated subdomain (`subdomain`); omit `deliveryMode` there. An explicit `path` there is not rejected: the publication is created on its subdomain and the result reports `deliveryModeMatched: false`, `deliveryModeReason: "policy:subdomain-required"` and a `Delivery notice:` line. Everything else in any namespace (Markdown, code/text, files, JSON, KV, public HTML) defaults to Promotion (`path`) and may choose Dedicated subdomain, including password-protected content. Promotion uses a BrewPage path with stricter active-document restrictions. Each NEW site gets one publication-specific host for its complete bundle, preserving relative/root-relative paths; missing assets return 404, with no SPA fallback. Third-party widgets may still need provider configuration.
|
|
110
110
|
|
|
@@ -132,7 +132,7 @@ update_hosting(type="html", namespace="public", id="aBcDeFgHiJ", ownerToken="tok
|
|
|
132
132
|
|
|
133
133
|
Publish HTML or Markdown content to BrewPage. Returns a public URL and owner token. Markdown raw HTML is rendered through an allowlist: scripts, styles, event handlers, forms, frames/embeds and `meta`/`base`/`link` are removed; links allow `http`, `https`, `mailto`, `tel` and relative URLs, images also `data:`; a lone unknown tag such as `<author>` shows as text.
|
|
134
134
|
|
|
135
|
-
Parameters: `content` (string), `format` (`HTML`
|
|
135
|
+
Parameters: `content` (string), `format` (default `HTML`; `HTML`, `MARKDOWN` or an alias the server maps, e.g. `md`), `namespace` (optional -- **omit for unlisted content**; pass `public` only for gallery/search eligibility, except when password-protected), `password` (optional), `ttlDays` (days or a string such as `2w`; default 15; the server clamps to 1--30), `filename` (optional, used as title fallback), `showTopBar` (optional boolean -- adds a toolbar with filename, Download button, and theme toggle), `deliveryMode` (optional).
|
|
136
136
|
|
|
137
137
|
The result includes `deliveryModeReason` and a `Delivery notice:` line when the server returns them (see above).
|
|
138
138
|
|
|
@@ -206,7 +206,7 @@ publish_file(url="https://example.com/diagram.png")
|
|
|
206
206
|
|
|
207
207
|
Publish a single-page or multi-file HTML site. Pass `entryContent` for a single page or `files` (array of `{path, content}`) for a multi-file site. Supports password protection, TTL, and owner token grouping.
|
|
208
208
|
|
|
209
|
-
Parameters: exactly one of `entryContent` (string) or non-empty `files` (array of `{path, content}`), `entry` (optional entry file path, default `index.html`), `namespace` (optional -- omit for unlisted content; `public` grants gallery eligibility except when password-protected), `password` (optional), `ttlDays` (
|
|
209
|
+
Parameters: exactly one of `entryContent` (string) or non-empty `files` (array of `{path, content}`), `entry` (optional entry file path, default `index.html`), `namespace` (optional -- omit for unlisted content; `public` grants gallery eligibility except when password-protected), `password` (optional), `ttlDays` (days or a string such as `2w`; default 15; the server clamps to 1--30), `ownerToken` (optional, groups site under an existing owner), `deliveryMode` (optional; fresh sites require `subdomain`).
|
|
210
210
|
|
|
211
211
|
Example prompt:
|
|
212
212
|
|
|
@@ -222,7 +222,7 @@ publish_site(files=[{"path": "index.html", "content": "..."}, {"path": "style.cs
|
|
|
222
222
|
|
|
223
223
|
Replace an owned site's complete file set at the same ID and primary link. Files absent from the new bundle are removed; matching files are overwritten and new files added. Hosting stays unchanged.
|
|
224
224
|
|
|
225
|
-
Parameters: `namespace`, `id`, `ownerToken`, exactly one of `entryContent` or a non-empty `files` array of `{path, content}`, optional `entry` (default `index.html`), `ttlDays` (
|
|
225
|
+
Parameters: `namespace`, `id`, `ownerToken`, exactly one of `entryContent` or a non-empty `files` array of `{path, content}`, optional `entry` (default `index.html`), `ttlDays` (ignored; existing expiry is preserved and a `ttl-ignored` notice is returned), and `tags`.
|
|
226
226
|
|
|
227
227
|
```text
|
|
228
228
|
republish_site(namespace="public", id="aBcDeFgHiJ", ownerToken="tok_...", files=[{"path":"index.html","content":"<h1>Updated site</h1>"}])
|
|
@@ -236,7 +236,7 @@ republish_site(namespace="public", id="aBcDeFgHiJ", ownerToken="tok_...", files=
|
|
|
236
236
|
|
|
237
237
|
Publish a JSON document to BrewPage. Returns a public URL and owner token. The body may be passed as a JSON string or as a structured object.
|
|
238
238
|
|
|
239
|
-
Parameters: `json` (string, object, or array), `namespace` (optional -- omit for unlisted content; `public` grants gallery/search eligibility, except when password-protected), `password` (optional), `ttlDays` (
|
|
239
|
+
Parameters: `json` (string, object, or array), `namespace` (optional -- omit for unlisted content; `public` grants gallery/search eligibility, except when password-protected), `password` (optional), `ttlDays` (days or a string such as `2w`; default 15; the server clamps to 1--30), `tags` (optional `string[]`), `ownerToken` (optional existing owner), `deliveryMode` (optional).
|
|
240
240
|
|
|
241
241
|
Example prompt:
|
|
242
242
|
|
|
@@ -286,7 +286,7 @@ update_json(namespace="public", id="aBcDeFgHiJ", json={"mode": "dark", "version"
|
|
|
286
286
|
|
|
287
287
|
Create a new KV (key/value) entry. Returns a public URL and owner token. The KV entry is addressed by `(namespace, id, key)`; this tool creates the entry and emits the generated `id` along with the owner token.
|
|
288
288
|
|
|
289
|
-
Parameters: `key` (string), `value` (string), `namespace` (optional -- omit for unlisted content; `public` grants gallery/search eligibility, except when password-protected), `password` (optional), `ttlDays` (
|
|
289
|
+
Parameters: `key` (string), `value` (string), `namespace` (optional -- omit for unlisted content; `public` grants gallery/search eligibility, except when password-protected), `password` (optional), `ttlDays` (days or a string such as `2w`; default 15; the server clamps to 1--30), `tags` (optional `string[]`), `ownerToken` (optional existing owner), `deliveryMode` (optional).
|
|
290
290
|
|
|
291
291
|
Example prompt:
|
|
292
292
|
|
|
@@ -433,6 +433,10 @@ Every publish response includes an **owner token** -- the only credential that a
|
|
|
433
433
|
|
|
434
434
|
## Changelog
|
|
435
435
|
|
|
436
|
+
## 1.11.0 -- 2026-10-21
|
|
437
|
+
|
|
438
|
+
- Every publish/update tool prints server `notices` as `Notice (code): message` lines. `ttlDays` takes a positive number or a string such as `2w`; the server rounds and clamps instead of the client rejecting values above 30. `publish_html` `format` accepts any string; the server maps aliases. `republish_site` TTL is ignored with a `ttl-ignored` notice. Same sixteen tools.
|
|
439
|
+
|
|
436
440
|
## 1.10.0 -- 2026-10-21
|
|
437
441
|
|
|
438
442
|
- `update_hosting`: `expectedVersion` is optional; a stale version, a locked mode or an OLD link answers with a successful result plus `deliveryModeReason` and a `Delivery notice:` line instead of an error. A publish request for `path` where `subdomain` is required succeeds on the subdomain and prints the notice. Same sixteen tools.
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { z } from "zod";
|
|
|
5
5
|
const BASE_URL = process.env.BREWPAGE_URL || "https://brewpage.app";
|
|
6
6
|
const server = new McpServer({
|
|
7
7
|
name: "brewpage-mcp",
|
|
8
|
-
version: "1.
|
|
8
|
+
version: "1.11.0",
|
|
9
9
|
});
|
|
10
10
|
const PUBLIC_NAMESPACE = "public";
|
|
11
11
|
/**
|
|
@@ -36,6 +36,8 @@ const NAMESPACE_DESCRIPTION = "Optional. Omit to generate an unlisted namespace:
|
|
|
36
36
|
"but it is excluded from gallery/search. Pass a custom namespace to group unlisted content, " +
|
|
37
37
|
"or pass `public` ONLY when the user explicitly wants gallery/search eligibility. " +
|
|
38
38
|
"Password-protected content stays excluded; unlisted, protected or otherwise ineligible native responses carry noindex; eligible public HTML, sites and files may permit indexing.";
|
|
39
|
+
const TTL_SCHEMA = z.union([z.number().positive(), z.string().min(1).max(32)]).optional().describe("Requested TTL: days as a number, or a string such as '2w', '36h' or '1 month' (default 15 days). " +
|
|
40
|
+
"The server rounds to whole days and clamps to the allowed range (1-30 by default; owner caps differ), reporting each adjustment in notices; use returned expiresAt.");
|
|
39
41
|
const DELIVERY_MODE_SCHEMA = z.enum(["path", "subdomain"]).optional().describe("Optional delivery choice for a fresh publication, independent of password/namespace. " +
|
|
40
42
|
"Fresh sites and HTML-format pages outside public (including the default unlisted namespace) always use subdomain; an explicit path there still publishes, on subdomain, with a delivery notice. " +
|
|
41
43
|
"Everything else in any namespace (Markdown, code/text, files, JSON, KV, public HTML) defaults to path (Promotion); public HTML may automatically choose subdomain for browser features. " +
|
|
@@ -49,8 +51,17 @@ function hostingResponseLines(data) {
|
|
|
49
51
|
if (data.deliveryModeMatched === false)
|
|
50
52
|
lines.push("Requested hosting differs from the effective mode; use the returned URL.");
|
|
51
53
|
lines.push(...deliveryReasonLines(data));
|
|
54
|
+
lines.push(...noticeLines(data));
|
|
52
55
|
return lines;
|
|
53
56
|
}
|
|
57
|
+
/** Server `notices` ({code, message}) on publish/update responses: each tolerated-input adjustment, verbatim. */
|
|
58
|
+
function noticeLines(data) {
|
|
59
|
+
if (!Array.isArray(data.notices))
|
|
60
|
+
return [];
|
|
61
|
+
return data.notices
|
|
62
|
+
.filter((n) => typeof n === "object" && n !== null && typeof n.code === "string" && typeof n.message === "string")
|
|
63
|
+
.map((n) => `Notice (${n.code}): ${n.message}`);
|
|
64
|
+
}
|
|
54
65
|
/** Optional delivery fields on HTML and hosting responses: why the mode was chosen, flagged or not applied. */
|
|
55
66
|
function deliveryReasonLines(data) {
|
|
56
67
|
const { deliveryModeReason: reason, deliveryNotice: notice } = data;
|
|
@@ -115,9 +126,10 @@ server.tool("publish_html", "Publish HTML or Markdown content to BrewPage (repos
|
|
|
115
126
|
content: z.string().describe("HTML or Markdown content to publish"),
|
|
116
127
|
deliveryMode: DELIVERY_MODE_SCHEMA,
|
|
117
128
|
format: z
|
|
118
|
-
.
|
|
129
|
+
.string()
|
|
130
|
+
.min(1)
|
|
119
131
|
.default("HTML")
|
|
120
|
-
.describe("Content format
|
|
132
|
+
.describe("Content format, default HTML. HTML or MARKDOWN; the server also maps aliases (md, text/markdown, file extensions, code languages) and detects unknown values from content, reporting the change in notices."),
|
|
121
133
|
namespace: z
|
|
122
134
|
.string()
|
|
123
135
|
.optional()
|
|
@@ -126,13 +138,7 @@ server.tool("publish_html", "Publish HTML or Markdown content to BrewPage (repos
|
|
|
126
138
|
.string()
|
|
127
139
|
.optional()
|
|
128
140
|
.describe("Optional password to protect the page"),
|
|
129
|
-
ttlDays:
|
|
130
|
-
.number()
|
|
131
|
-
.int()
|
|
132
|
-
.min(1)
|
|
133
|
-
.max(30)
|
|
134
|
-
.optional()
|
|
135
|
-
.describe("Requested TTL in days (1-30, default 15). Backend owner caps and eligible automatic extensions can affect expiry; use returned expiresAt."),
|
|
141
|
+
ttlDays: TTL_SCHEMA,
|
|
136
142
|
filename: z
|
|
137
143
|
.string()
|
|
138
144
|
.max(200)
|
|
@@ -382,12 +388,7 @@ server.tool("publish_site", "Publish an HTML site to BrewPage. Single-page: pass
|
|
|
382
388
|
.string()
|
|
383
389
|
.optional()
|
|
384
390
|
.describe("Optional password to protect the site"),
|
|
385
|
-
ttlDays:
|
|
386
|
-
.number()
|
|
387
|
-
.min(1)
|
|
388
|
-
.max(30)
|
|
389
|
-
.optional()
|
|
390
|
-
.describe("Requested TTL in days (1-30, default 15). Backend owner caps and eligible automatic extensions can affect expiry; use returned expiresAt."),
|
|
391
|
+
ttlDays: TTL_SCHEMA,
|
|
391
392
|
ownerToken: z
|
|
392
393
|
.string()
|
|
393
394
|
.optional()
|
|
@@ -494,12 +495,7 @@ server.tool("republish_site", "Republish (full-replace) an existing multi-file B
|
|
|
494
495
|
.string()
|
|
495
496
|
.optional()
|
|
496
497
|
.describe("Entry file path, default index.html"),
|
|
497
|
-
ttlDays:
|
|
498
|
-
.number()
|
|
499
|
-
.min(1)
|
|
500
|
-
.max(30)
|
|
501
|
-
.optional()
|
|
502
|
-
.describe("Compatibility input (1-30); site republishing preserves existing expiry. Use returned expiresAt."),
|
|
498
|
+
ttlDays: TTL_SCHEMA.describe("Ignored: republishing keeps the existing expiry; a supplied value comes back as a ttl-ignored notice."),
|
|
503
499
|
tags: z
|
|
504
500
|
.array(z.string())
|
|
505
501
|
.optional()
|
|
@@ -634,13 +630,7 @@ server.tool("publish_json", "Publish a JSON document to BrewPage (repository def
|
|
|
634
630
|
.string()
|
|
635
631
|
.optional()
|
|
636
632
|
.describe("Optional password to protect the document"),
|
|
637
|
-
ttlDays:
|
|
638
|
-
.number()
|
|
639
|
-
.int()
|
|
640
|
-
.min(1)
|
|
641
|
-
.max(30)
|
|
642
|
-
.optional()
|
|
643
|
-
.describe("Requested TTL in days (1-30, default 15). Backend owner caps and eligible automatic extensions can affect expiry; use returned expiresAt."),
|
|
633
|
+
ttlDays: TTL_SCHEMA,
|
|
644
634
|
tags: z
|
|
645
635
|
.array(z.string())
|
|
646
636
|
.optional()
|
|
@@ -780,13 +770,7 @@ server.tool("publish_kv", "Publish a key/value entry to BrewPage. Creates a KV s
|
|
|
780
770
|
.string()
|
|
781
771
|
.optional()
|
|
782
772
|
.describe("Optional password to protect the KV store"),
|
|
783
|
-
ttlDays:
|
|
784
|
-
.number()
|
|
785
|
-
.int()
|
|
786
|
-
.min(1)
|
|
787
|
-
.max(30)
|
|
788
|
-
.optional()
|
|
789
|
-
.describe("Requested TTL in days (1-30, default 15). Backend owner caps and eligible automatic extensions can affect expiry; use returned expiresAt."),
|
|
773
|
+
ttlDays: TTL_SCHEMA,
|
|
790
774
|
tags: z
|
|
791
775
|
.array(z.string())
|
|
792
776
|
.optional()
|
package/package.json
CHANGED