brewpage-mcp 1.14.4 → 1.14.5
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 +11 -7
- package/dist/tools.d.ts +1 -1
- package/dist/tools.js +17 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ Choosing a host? See how BrewPage compares with GitHub Pages, Netlify Drop, Tiin
|
|
|
17
17
|
## Quick Start
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
npx -y brewpage-mcp@1.14.
|
|
20
|
+
npx -y brewpage-mcp@1.14.5
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
Requires Node.js 20 or newer. This starts the stdio server for an MCP client.
|
|
@@ -33,7 +33,7 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)
|
|
|
33
33
|
"mcpServers": {
|
|
34
34
|
"brewpage": {
|
|
35
35
|
"command": "npx",
|
|
36
|
-
"args": ["-y", "brewpage-mcp@1.14.
|
|
36
|
+
"args": ["-y", "brewpage-mcp@1.14.5"]
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -44,7 +44,7 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)
|
|
|
44
44
|
Register a project-scoped stdio server:
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
|
-
claude mcp add --transport stdio --scope project brewpage -- npx -y brewpage-mcp@1.14.
|
|
47
|
+
claude mcp add --transport stdio --scope project brewpage -- npx -y brewpage-mcp@1.14.5
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
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).
|
|
@@ -58,7 +58,7 @@ Open **Settings > MCP** and add:
|
|
|
58
58
|
"mcpServers": {
|
|
59
59
|
"brewpage": {
|
|
60
60
|
"command": "npx",
|
|
61
|
-
"args": ["-y", "brewpage-mcp@1.14.
|
|
61
|
+
"args": ["-y", "brewpage-mcp@1.14.5"]
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
}
|
|
@@ -72,7 +72,7 @@ Open the Cline MCP settings panel and add:
|
|
|
72
72
|
{
|
|
73
73
|
"brewpage": {
|
|
74
74
|
"command": "npx",
|
|
75
|
-
"args": ["-y", "brewpage-mcp@1.14.
|
|
75
|
+
"args": ["-y", "brewpage-mcp@1.14.5"]
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
```
|
|
@@ -80,7 +80,7 @@ Open the Cline MCP settings panel and add:
|
|
|
80
80
|
### Global Install
|
|
81
81
|
|
|
82
82
|
```bash
|
|
83
|
-
npm install -g brewpage-mcp@1.14.
|
|
83
|
+
npm install -g brewpage-mcp@1.14.5
|
|
84
84
|
brewpage-mcp
|
|
85
85
|
```
|
|
86
86
|
|
|
@@ -215,7 +215,7 @@ publish_file(url="https://example.com/diagram.png")
|
|
|
215
215
|
|
|
216
216
|
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.
|
|
217
217
|
|
|
218
|
-
Limits (current values from `get_limits`): a request is at most 25 MB; a site at most 200 files, 5 MB per file and 20 MB in total; each path at most 380 characters. System files such as `.DS_Store` and `__MACOSX/` are skipped and never count; files with an unsupported extension or a too-long path are skipped and reported in notices. Entry: `entry`, else root `index.html`, else the shallowest HTML file. A site limit hit answers 400 with a message naming the limit; 413 means the request is over 25 MB, has too many files and form fields, or a file name/path is too long; 422 means no servable file is left.
|
|
218
|
+
Limits (current values from `get_limits`): a request is at most 25 MB; a site at most 200 files, 5 MB per file and 20 MB in total; each path at most 380 characters. System files such as `.DS_Store` and `__MACOSX/` are skipped and never count; files with an unsupported extension or a too-long path are skipped and reported in notices. Entry: `entry`, else root `index.html`, else the shallowest HTML file. A site limit hit answers 400 with a message naming the limit, as does a PDF/Office file that is unreadable, password-protected or too complex; 413 means the request is over 25 MB, has too many files and form fields, or a file name/path is too long; 422 means no servable file is left; 503 means busy: retry after `Retry-After` seconds (failed publish tools print it).
|
|
219
219
|
|
|
220
220
|
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 private, unlisted content; `public` lists the site in the gallery and sitemap for Google, Bing and AI search; a site always gets its own subdomain), `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`).
|
|
221
221
|
|
|
@@ -513,6 +513,10 @@ Every publish response includes an **owner token** -- the only credential that a
|
|
|
513
513
|
|
|
514
514
|
## Changelog
|
|
515
515
|
|
|
516
|
+
## 1.14.5 -- 2026-10-27
|
|
517
|
+
|
|
518
|
+
- Site publish hints add 400 for an unreadable, password-protected or too complex PDF/Office file and 503 when busy; a failed publish on 503 prints `Retry-After`.
|
|
519
|
+
|
|
516
520
|
## 1.14.4 -- 2026-10-26
|
|
517
521
|
|
|
518
522
|
- Remote mode: a request keeps its slot until the tool finishes, and a client disconnect cancels its backend calls and source download; backend calls time out after 60 s. Separate pools for light, write and large calls queue briefly instead of refusing; request body up to 32 MiB. `BREWPAGE_SHARED_EGRESS_CIDRS` and `BREWPAGE_SHARED_EGRESS_LIST_URLS` exempt platform egress from per-IP caps. Tools are unchanged.
|
package/dist/tools.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
export declare const DEFAULT_BASE_URL = "https://brewpage.app";
|
|
3
|
-
export declare const USER_AGENT = "brewpage-mcp/1.14.
|
|
3
|
+
export declare const USER_AGENT = "brewpage-mcp/1.14.5";
|
|
4
4
|
export declare const OWNER_TOKEN_ENV = "BREWPAGE_OWNER_TOKEN";
|
|
5
5
|
export interface ServerOptions {
|
|
6
6
|
/** BrewPage origin for API calls; default https://brewpage.app. */
|
package/dist/tools.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
export const DEFAULT_BASE_URL = "https://brewpage.app";
|
|
4
|
-
export const USER_AGENT = "brewpage-mcp/1.14.
|
|
4
|
+
export const USER_AGENT = "brewpage-mcp/1.14.5";
|
|
5
5
|
export const OWNER_TOKEN_ENV = "BREWPAGE_OWNER_TOKEN";
|
|
6
6
|
const READ_ONLY = { readOnlyHint: true };
|
|
7
7
|
const DESTRUCTIVE = { readOnlyHint: false, destructiveHint: true };
|
|
@@ -46,9 +46,14 @@ function maskToken(token) {
|
|
|
46
46
|
function textResult(text, isError = false) {
|
|
47
47
|
return isError ? { content: [{ type: "text", text }], isError: true } : { content: [{ type: "text", text }] };
|
|
48
48
|
}
|
|
49
|
+
/** ` Retry-After: <value>.` for a busy 503 that sends the header, else empty. */
|
|
50
|
+
function retryAfterText(status, headers) {
|
|
51
|
+
const after = status === 503 ? headers?.get("retry-after") : null;
|
|
52
|
+
return after ? ` Retry-After: ${after}.` : "";
|
|
53
|
+
}
|
|
49
54
|
/** Owner-tool failure: the server answer verbatim plus a hint for a plain wrong-token 403 or a frozen old publication. */
|
|
50
|
-
function ownerFailure(operation, status, data, fromEnv) {
|
|
51
|
-
const lines = [`Failed to ${operation} (${status}): ${JSON.stringify(data)}`];
|
|
55
|
+
function ownerFailure(operation, status, data, fromEnv, headers) {
|
|
56
|
+
const lines = [`Failed to ${operation} (${status}): ${JSON.stringify(data)}${retryAfterText(status, headers)}`];
|
|
52
57
|
const code = data?.code;
|
|
53
58
|
if (status === 403 && (code === undefined || code === "OWNER_AUTHORIZATION_FAILED")) {
|
|
54
59
|
lines.push(`Wrong owner token for this publication. Use ownerToken from create.${fromEnv ? ` Sent: ${OWNER_TOKEN_ENV}.` : ""}`);
|
|
@@ -106,8 +111,9 @@ const DELIVERY_MODE_SCHEMA = z.enum(["path", "subdomain"]).optional().describe("
|
|
|
106
111
|
const SITE_LIMITS_TEXT = "Default limits (current values: GET /api/limits): a request is at most 25 MB; a site at most 200 files, 5 MB per file and 20 MB in total; " +
|
|
107
112
|
"each path at most 380 characters. System files (.DS_Store, __MACOSX/ and similar) are skipped and never count; files with an unsupported extension " +
|
|
108
113
|
"or a too-long path are skipped and listed in notices. Entry: `entry`, else root index.html, else the shallowest HTML file. " +
|
|
109
|
-
"Errors: 400 = a site limit exceeded (the message names it), invalid path
|
|
110
|
-
"too many files and form fields, or a file name/path too long;
|
|
114
|
+
"Errors: 400 = a site limit exceeded (the message names it), invalid path, no HTML file, or a PDF/Office file unreadable, " +
|
|
115
|
+
"password-protected or too complex; 413 = request over 25 MB, too many files and form fields, or a file name/path too long; " +
|
|
116
|
+
"422 = no servable file left; 503 = busy, retry after Retry-After seconds.";
|
|
111
117
|
function hostingResponseLines(data) {
|
|
112
118
|
const fields = ["routingCohort", "deliveryMode", "requestedDeliveryMode", "effectiveDeliveryMode",
|
|
113
119
|
"deliveryModeMatched", "modeLocked", "hostingVersion", "access", "managementLink"];
|
|
@@ -182,7 +188,7 @@ export function createServer(options = {}) {
|
|
|
182
188
|
const apiFetch = options.fetch ?? fetch;
|
|
183
189
|
const server = new McpServer({
|
|
184
190
|
name: "brewpage-mcp",
|
|
185
|
-
version: "1.14.
|
|
191
|
+
version: "1.14.5",
|
|
186
192
|
});
|
|
187
193
|
/** Caller argument first, then the configured default; `fromEnv` marks the configured one. */
|
|
188
194
|
function ownerTokenFor(argument) {
|
|
@@ -300,13 +306,13 @@ export function createServer(options = {}) {
|
|
|
300
306
|
const owner = ownerTokenFor(ownerToken).token;
|
|
301
307
|
if (owner)
|
|
302
308
|
headers["X-Owner-Token"] = owner;
|
|
303
|
-
const { ok, data } = await apiRequest("POST", path, body, headers);
|
|
309
|
+
const { ok, status, data, headers: answerHeaders } = await apiRequest("POST", path, body, headers);
|
|
304
310
|
if (!ok) {
|
|
305
311
|
return {
|
|
306
312
|
content: [
|
|
307
313
|
{
|
|
308
314
|
type: "text",
|
|
309
|
-
text: `Failed to publish: ${JSON.stringify(data)}`,
|
|
315
|
+
text: `Failed to publish: ${JSON.stringify(data)}${retryAfterText(status, answerHeaders)}`,
|
|
310
316
|
},
|
|
311
317
|
],
|
|
312
318
|
isError: true,
|
|
@@ -357,7 +363,7 @@ export function createServer(options = {}) {
|
|
|
357
363
|
content: [
|
|
358
364
|
{
|
|
359
365
|
type: "text",
|
|
360
|
-
text: `Failed to upload file: ${JSON.stringify(data)}`,
|
|
366
|
+
text: `Failed to upload file: ${JSON.stringify(data)}${retryAfterText(res.status, res.headers)}`,
|
|
361
367
|
},
|
|
362
368
|
],
|
|
363
369
|
isError: true,
|
|
@@ -577,7 +583,7 @@ export function createServer(options = {}) {
|
|
|
577
583
|
content: [
|
|
578
584
|
{
|
|
579
585
|
type: "text",
|
|
580
|
-
text: `Failed to publish site: ${JSON.stringify(data)}`,
|
|
586
|
+
text: `Failed to publish site: ${JSON.stringify(data)}${retryAfterText(res.status, res.headers)}`,
|
|
581
587
|
},
|
|
582
588
|
],
|
|
583
589
|
isError: true,
|
|
@@ -673,7 +679,7 @@ export function createServer(options = {}) {
|
|
|
673
679
|
const res = await bpFetch(url, { method: "PUT", headers, body: formData });
|
|
674
680
|
const data = await res.json().catch(() => null);
|
|
675
681
|
if (!res.ok)
|
|
676
|
-
return ownerFailure("republish site", res.status, data, auth.fromEnv);
|
|
682
|
+
return ownerFailure("republish site", res.status, data, auth.fromEnv, res.headers);
|
|
677
683
|
const site = data;
|
|
678
684
|
const lines = [
|
|
679
685
|
`Site republished successfully (full replace)!`,
|
package/package.json
CHANGED