brewpage-mcp 1.16.5 → 1.16.7
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 +14 -6
- package/dist/tools.d.ts +1 -1
- package/dist/tools.js +27 -19
- 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.16.
|
|
20
|
+
npx -y brewpage-mcp@1.16.7
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
Requires Node.js 20 or newer. This starts the stdio server for an MCP client.
|
|
@@ -50,7 +50,7 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)
|
|
|
50
50
|
"mcpServers": {
|
|
51
51
|
"brewpage": {
|
|
52
52
|
"command": "npx",
|
|
53
|
-
"args": ["-y", "brewpage-mcp@1.16.
|
|
53
|
+
"args": ["-y", "brewpage-mcp@1.16.7"]
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
}
|
|
@@ -61,7 +61,7 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)
|
|
|
61
61
|
Register a project-scoped stdio server:
|
|
62
62
|
|
|
63
63
|
```bash
|
|
64
|
-
claude mcp add --transport stdio --scope project brewpage -- npx -y brewpage-mcp@1.16.
|
|
64
|
+
claude mcp add --transport stdio --scope project brewpage -- npx -y brewpage-mcp@1.16.7
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
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).
|
|
@@ -75,7 +75,7 @@ Open **Settings > MCP** and add:
|
|
|
75
75
|
"mcpServers": {
|
|
76
76
|
"brewpage": {
|
|
77
77
|
"command": "npx",
|
|
78
|
-
"args": ["-y", "brewpage-mcp@1.16.
|
|
78
|
+
"args": ["-y", "brewpage-mcp@1.16.7"]
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
}
|
|
@@ -89,7 +89,7 @@ Open the Cline MCP settings panel and add:
|
|
|
89
89
|
{
|
|
90
90
|
"brewpage": {
|
|
91
91
|
"command": "npx",
|
|
92
|
-
"args": ["-y", "brewpage-mcp@1.16.
|
|
92
|
+
"args": ["-y", "brewpage-mcp@1.16.7"]
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
```
|
|
@@ -97,7 +97,7 @@ Open the Cline MCP settings panel and add:
|
|
|
97
97
|
### Global Install
|
|
98
98
|
|
|
99
99
|
```bash
|
|
100
|
-
npm install -g brewpage-mcp@1.16.
|
|
100
|
+
npm install -g brewpage-mcp@1.16.7
|
|
101
101
|
brewpage-mcp
|
|
102
102
|
```
|
|
103
103
|
|
|
@@ -530,6 +530,14 @@ Every publish response includes an **owner token** -- the only credential that a
|
|
|
530
530
|
|
|
531
531
|
## Changelog
|
|
532
532
|
|
|
533
|
+
## 1.16.7 -- 2026-11-01
|
|
534
|
+
|
|
535
|
+
- Owner tools answer a 404 `WRONG_RESOURCE_TYPE` (this id lives under another type) with the server body plus the `resourceUrl` to repeat the write at, instead of the publish-anew hint. Contract 2.8.58.
|
|
536
|
+
|
|
537
|
+
## 1.16.6 -- 2026-10-31
|
|
538
|
+
|
|
539
|
+
- `publish_html`, `publish_file` and `publish_site` descriptions lead with `namespace=public` to be found (gallery + Google, Bing & AI search; omitted: private); the `namespace` input names what to publish publicly (docs, guides, demos, portfolios, reports, landing pages) and the generated `priv-*` default; the private result line says how to be found. Shorter texts, no new facts.
|
|
540
|
+
|
|
533
541
|
## 1.16.5 -- 2026-10-30
|
|
534
542
|
|
|
535
543
|
- `update_html` takes optional `tags` (sent as `?tags=a,b`); `update_html` and `republish_site` tags replace the stored tags, `[]` clears them, omitted keeps them. A 429 on any write prints the server's `Retry-After` beside the verbatim body (`retryAfterSeconds`).
|
package/dist/tools.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/server";
|
|
2
2
|
export declare const DEFAULT_BASE_URL = "https://brewpage.app";
|
|
3
|
-
export declare const USER_AGENT = "brewpage-mcp/1.16.
|
|
3
|
+
export declare const USER_AGENT = "brewpage-mcp/1.16.7";
|
|
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/server";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
export const DEFAULT_BASE_URL = "https://brewpage.app";
|
|
4
|
-
export const USER_AGENT = "brewpage-mcp/1.16.
|
|
4
|
+
export const USER_AGENT = "brewpage-mcp/1.16.7";
|
|
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 };
|
|
@@ -21,6 +21,7 @@ const SECRETS = "Secrets allowed; likely ones are flagged in notices. Private na
|
|
|
21
21
|
NO_PUBLIC_CREDENTIALS;
|
|
22
22
|
const MANAGE_URL_TEXT = "Returns manageUrl, a private management link (grants control; not for public sharing).";
|
|
23
23
|
const OLD_READ_ONLY_CODE = "OLD_PUBLICATION_READ_ONLY";
|
|
24
|
+
const WRONG_TYPE_CODE = "WRONG_RESOURCE_TYPE";
|
|
24
25
|
const OLD_READ_ONLY_TEXT = ` Old publications (made before 5 October 2026) are read-only: 409 ${OLD_READ_ONLY_CODE} with createUrl to publish anew.`;
|
|
25
26
|
/** Notice codes the agent must relay to the user. */
|
|
26
27
|
const WARNING_CODES = new Set(["secret-detected"]);
|
|
@@ -63,14 +64,18 @@ function retryAfterText(status, headers) {
|
|
|
63
64
|
const PUBLISH_TOOL_FOR = {
|
|
64
65
|
"update HTML": "publish_html", "republish site": "publish_site", "update JSON": "publish_json", "set KV": "publish_kv",
|
|
65
66
|
};
|
|
66
|
-
/** Owner-tool failure:
|
|
67
|
+
/** Owner-tool failure: server answer verbatim plus a hint for wrong-token 403, wrong-type or missing row, frozen old publication. */
|
|
67
68
|
function ownerFailure(operation, status, data, fromEnv, headers) {
|
|
68
69
|
const lines = [`Failed to ${operation} (${status}): ${JSON.stringify(data)}${retryAfterText(status, headers)}`];
|
|
69
70
|
const code = data?.code;
|
|
70
71
|
if (status === 403 && (code === undefined || code === "OWNER_AUTHORIZATION_FAILED")) {
|
|
71
72
|
lines.push(`Wrong owner token for this publication. Use ownerToken from create.${fromEnv ? ` Sent: ${OWNER_TOKEN_ENV}.` : ""}`);
|
|
72
73
|
}
|
|
73
|
-
|
|
74
|
+
const resourceUrl = data?.resourceUrl;
|
|
75
|
+
if (status === 404 && code === WRONG_TYPE_CODE && typeof resourceUrl === "string") {
|
|
76
|
+
lines.push(`Wrong type for this id: repeat the write at resourceUrl (${resourceUrl}).`);
|
|
77
|
+
}
|
|
78
|
+
else if (status === 404 && PUBLISH_TOOL_FOR[operation]) {
|
|
74
79
|
lines.push(`Use the ${PUBLISH_TOOL_FOR[operation]} tool to publish a new copy.`);
|
|
75
80
|
}
|
|
76
81
|
if (status === 409 && code === OLD_READ_ONLY_CODE) {
|
|
@@ -99,17 +104,19 @@ function resolveNamespace(namespace) {
|
|
|
99
104
|
return namespace && namespace.length > 0 ? namespace : defaultPrivateNamespace();
|
|
100
105
|
}
|
|
101
106
|
const UNLISTED_NOTICE = "Private: not listed. Anyone with the link can open it.";
|
|
102
|
-
const LISTABLE_HINT = "
|
|
107
|
+
const LISTABLE_HINT = " To be found, send namespace=public: gallery + Google, Bing & AI search.";
|
|
103
108
|
const PROTECTED_UNLISTED_NOTICE = "Password: link + password. Not listed.";
|
|
104
|
-
const PUBLIC_NAMESPACE_LEAD = "namespace=public
|
|
105
|
-
"
|
|
109
|
+
const PUBLIC_NAMESPACE_LEAD = "Send namespace=public for anything meant to be found or shared (docs, guides, demos, portfolios, reports, landing pages): " +
|
|
110
|
+
"listed in the public gallery and sitemap, so Google, Bing and AI search index it and people discover it. ";
|
|
106
111
|
const PUBLIC_NAMESPACE_TAIL = " Anyone can find and read a public page, so it is unsuitable for secrets, tokens or personal data. " +
|
|
107
|
-
"Omit (default): private
|
|
112
|
+
"Omit (default): private, a generated priv-* namespace; unlisted, not indexed; the link still opens it. ";
|
|
113
|
+
/** Tool-description lead for listable publish tools. */
|
|
114
|
+
const PUBLIC_HINT = "Send namespace=public to be found: gallery + Google, Bing & AI search. Omitted: private. ";
|
|
108
115
|
const NAMESPACE_FORMAT = "Lowercase only: 1-32 of a-z, 0-9, hyphen.";
|
|
109
116
|
/** `namespace` for publish_html and publish_file. */
|
|
110
117
|
const NAMESPACE_DESCRIPTION = PUBLIC_NAMESPACE_LEAD +
|
|
111
|
-
"Public pages are served
|
|
112
|
-
"
|
|
118
|
+
"Public pages are served on the brewpage.app domain itself, for the strongest search reach; " +
|
|
119
|
+
"code that needs its own origin (cookies, storage) gets its own subdomain automatically." +
|
|
113
120
|
PUBLIC_NAMESPACE_TAIL + NAMESPACE_FORMAT;
|
|
114
121
|
const SITE_NAMESPACE_DESCRIPTION = PUBLIC_NAMESPACE_LEAD + "A site always gets its own subdomain." +
|
|
115
122
|
PUBLIC_NAMESPACE_TAIL + NAMESPACE_FORMAT;
|
|
@@ -123,9 +130,9 @@ const DELIVERY_MODE_SCHEMA = z.enum(["path", "subdomain"]).optional().describe("
|
|
|
123
130
|
"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. " +
|
|
124
131
|
"When creation returns an existing publication, it keeps its actual mode and URL.");
|
|
125
132
|
/** Site upload rules shared by publish_site and republish_site; current values come from get_limits. */
|
|
126
|
-
const SITE_LIMITS_TEXT = "Default limits (current
|
|
127
|
-
"
|
|
128
|
-
"or
|
|
133
|
+
const SITE_LIMITS_TEXT = "Default limits (current: GET /api/limits): request 25 MiB; site 200 files, 5 MiB per file, 20 MiB total; " +
|
|
134
|
+
"path 380 characters. System files (.DS_Store, __MACOSX/ and similar) are skipped and never count; files with an unsupported extension " +
|
|
135
|
+
"or too-long path are skipped and listed in notices. Entry: `entry`, else root index.html, else the shallowest HTML file. " +
|
|
129
136
|
"Errors: 400 = a site limit exceeded (the message names it), invalid path, no HTML file, or a PDF/Office file unreadable " +
|
|
130
137
|
"or password-protected; 413 = request over 25 MiB, too many files and form fields, or a file name/path too long; " +
|
|
131
138
|
"422 = no servable file left; 503 = busy, retry after Retry-After seconds.";
|
|
@@ -216,7 +223,7 @@ export function createServer(options = {}) {
|
|
|
216
223
|
const apiFetch = options.fetch ?? fetch;
|
|
217
224
|
const server = new McpServer({
|
|
218
225
|
name: "brewpage-mcp",
|
|
219
|
-
version: "1.16.
|
|
226
|
+
version: "1.16.7",
|
|
220
227
|
});
|
|
221
228
|
/** Caller argument first, then the configured default; `fromEnv` marks the configured one. */
|
|
222
229
|
function ownerTokenFor(argument) {
|
|
@@ -291,9 +298,10 @@ export function createServer(options = {}) {
|
|
|
291
298
|
}
|
|
292
299
|
server.registerTool("publish_html", {
|
|
293
300
|
...toolMeta("Publish HTML, Markdown, code or JSON page", ADDITIVE),
|
|
294
|
-
description: "Publish HTML, Markdown, code or JSON
|
|
295
|
-
"
|
|
296
|
-
"
|
|
301
|
+
description: "Publish HTML, Markdown, code or JSON to BrewPage (max 5 MiB). " + PUBLIC_HINT +
|
|
302
|
+
"Format omitted -> server detects it. Returns its primary share link and owner token. Optional password, TTL, filename, top toolbar (showTopBar). " +
|
|
303
|
+
"A `public` page without deliveryMode may get its own subdomain if it needs browser features a BrewPage link lacks; " +
|
|
304
|
+
"the result then has deliveryModeReason and a delivery notice. Markdown raw HTML is allowlisted: scripts, styles, event handlers, forms, embeds removed. " +
|
|
297
305
|
MANAGE_URL_TEXT + " " + SECRETS,
|
|
298
306
|
inputSchema: {
|
|
299
307
|
content: z.string().describe("HTML, Markdown, code or JSON to publish"),
|
|
@@ -362,7 +370,7 @@ export function createServer(options = {}) {
|
|
|
362
370
|
});
|
|
363
371
|
server.registerTool("publish_file", {
|
|
364
372
|
...toolMeta("Publish file from URL", ADDITIVE),
|
|
365
|
-
description: "Upload a file
|
|
373
|
+
description: "Upload a file from a URL. " + PUBLIC_HINT + "Max 5 MiB, video 20 MiB; no password or TTL. Returns its primary share link and owner token. " +
|
|
366
374
|
MANAGE_URL_TEXT + " " + SECRETS,
|
|
367
375
|
inputSchema: {
|
|
368
376
|
url: z.string().url().describe("URL of the file to upload"),
|
|
@@ -545,8 +553,8 @@ export function createServer(options = {}) {
|
|
|
545
553
|
});
|
|
546
554
|
server.registerTool("publish_site", {
|
|
547
555
|
...toolMeta("Publish site", ADDITIVE),
|
|
548
|
-
description: "Publish an HTML site to BrewPage. Single-page: `entryContent`. Multi-page: `files` (
|
|
549
|
-
"Static
|
|
556
|
+
description: "Publish an HTML site to BrewPage. " + PUBLIC_HINT + "Single-page: `entryContent`. Multi-page: `files` (`{path, content}` array). Optional `entry` overrides `index.html`. Returns its primary share link and owner token. " +
|
|
557
|
+
"Static only: HTML, CSS, JS (incl. built React/Vue bundles) run in the browser; server code (PHP etc.) never runs. " + SITE_LIMITS_TEXT +
|
|
550
558
|
" " + MANAGE_URL_TEXT + " " + SECRETS,
|
|
551
559
|
inputSchema: {
|
|
552
560
|
deliveryMode: DELIVERY_MODE_SCHEMA,
|
package/package.json
CHANGED