brewpage-mcp 1.11.0 → 1.12.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.
Files changed (3) hide show
  1. package/README.md +34 -9
  2. package/dist/index.js +33 -3
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -7,12 +7,12 @@ MCP server for [BrewPage](https://brewpage.app) -- publish and manage HTML, KV,
7
7
 
8
8
  ## What is BrewPage
9
9
 
10
- [BrewPage](https://brewpage.app) is a free instant hosting platform designed for AI agents and developers. One `POST` request publishes HTML, Markdown, a multi-file site, a JSON document, or a binary file and returns its primary HTTPS link -- no accounts, no API keys, no infrastructure setup. Every resource carries an **owner token** returned at creation time: use it to update content in place, delete the resource, or authenticate list operations across sessions. `brewpage-mcp` exposes this API as sixteen typed MCP tools so any compatible agent -- Claude, Codex, Gemini, Cursor, Cline -- can publish, update, fetch, and manage BrewPage HTML, JSON, KV, and file content without leaving the conversation.
10
+ [BrewPage](https://brewpage.app) is a free instant hosting platform designed for AI agents and developers. One `POST` request publishes HTML, Markdown, a multi-file site, a JSON document, or a binary file and returns its primary HTTPS link -- no accounts, no API keys, no infrastructure setup. Every resource carries an **owner token** returned at creation time: use it to update content in place, delete the resource, or authenticate list operations across sessions. `brewpage-mcp` exposes this API as seventeen typed MCP tools so any compatible agent -- Claude, Codex, Gemini, Cursor, Cline -- can publish, update, fetch, and manage BrewPage HTML, JSON, KV, and file content without leaving the conversation.
11
11
 
12
12
  ## Quick Start
13
13
 
14
14
  ```bash
15
- npx -y brewpage-mcp@1.11.0
15
+ npx -y brewpage-mcp@1.12.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.11.0"]
31
+ "args": ["-y", "brewpage-mcp@1.12.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.11.0
42
+ claude mcp add --transport stdio --scope project brewpage -- npx -y brewpage-mcp@1.12.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.11.0"]
56
+ "args": ["-y", "brewpage-mcp@1.12.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.11.0"]
70
+ "args": ["-y", "brewpage-mcp@1.12.0"]
71
71
  }
72
72
  }
73
73
  ```
@@ -75,13 +75,13 @@ Open the Cline MCP settings panel and add:
75
75
  ### Global Install
76
76
 
77
77
  ```bash
78
- npm install -g brewpage-mcp@1.11.0
78
+ npm install -g brewpage-mcp@1.12.0
79
79
  brewpage-mcp
80
80
  ```
81
81
 
82
82
  ## Tools
83
83
 
84
- Sixteen tools are available. Creation returns an owner token; keep it to modify or delete the resource later. Updates (`PUT`/`PATCH`) require the original `ownerToken`. Supported password inputs use `X-Password`.
84
+ Seventeen tools are available. Creation returns an owner token; keep it to modify or delete the resource later. Updates (`PUT`/`PATCH`) require the original `ownerToken`. Supported password inputs use `X-Password`.
85
85
 
86
86
  | Tool | Purpose |
87
87
  |------|---------|
@@ -101,6 +101,7 @@ Sixteen tools are available. Creation returns an owner token; keep it to modify
101
101
  | `delete_resource` | Delete HTML, JSON, KV, or file content |
102
102
  | `search_gallery` | Browse public content or list owned resources |
103
103
  | `get_stats` | Read platform-wide statistics |
104
+ | `get_limits` | Read the current upload limits (`GET /api/limits`) |
104
105
 
105
106
  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
107
 
@@ -206,6 +207,8 @@ publish_file(url="https://example.com/diagram.png")
206
207
 
207
208
  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
209
 
210
+ 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.
211
+
209
212
  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
213
 
211
214
  Example prompt:
@@ -220,7 +223,7 @@ publish_site(files=[{"path": "index.html", "content": "..."}, {"path": "style.cs
220
223
 
221
224
  ### `republish_site`
222
225
 
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.
226
+ 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. The `publish_site` limits and status codes apply.
224
227
 
225
228
  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
229
 
@@ -382,6 +385,22 @@ Example prompt:
382
385
  get_stats()
383
386
  ```
384
387
 
388
+ ---
389
+
390
+ ### `get_limits`
391
+
392
+ Read the current upload limits from `GET /api/limits` (no auth). Sizes are bytes: `requestMaxBytes` plus `sites.maxFiles`, `maxFileBytes`, `maxTotalBytes` (uncompressed), `maxArchiveExpansionBytes`, `maxPathChars`, `maxPathBytes`, `maxNameBytes`, `defaultTtlDays`, `maxTtlDays`, `allowedExtensions`, `skippedFileNames` and `skippedRootFolders`. Call it before publishing a large or multi-file site.
393
+
394
+ Parameters: none.
395
+
396
+ Example prompt:
397
+
398
+ > "How many files can a BrewPage site have?"
399
+
400
+ ```
401
+ get_limits()
402
+ ```
403
+
385
404
  ## Common LLM Query to BrewPage Tool Mapping
386
405
 
387
406
  | LLM query / intent | Tool | Notes |
@@ -397,6 +416,7 @@ get_stats()
397
416
  | "Remove the page I published" | `delete_resource` | Requires `ownerToken` from creation |
398
417
  | "Read back the page I published" | `get_page` | Returns raw content for editing |
399
418
  | "How many pages are on BrewPage?" | `get_stats` | Returns platform totals |
419
+ | "How big can my site be?" | `get_limits` | Current request and site limits in bytes |
400
420
  | "Store JSON state between turns" | `publish_json` | Returns short URL + owner token |
401
421
  | "Read that JSON document back" | `get_json` | By `namespace` + `id` |
402
422
  | "Update the JSON I stored" | `update_json` | Requires `ownerToken`; preserves URL |
@@ -433,6 +453,11 @@ Every publish response includes an **owner token** -- the only credential that a
433
453
 
434
454
  ## Changelog
435
455
 
456
+ ## 1.12.0 -- 2026-10-22
457
+
458
+ - New `get_limits` tool reads `GET /api/limits`: request size, site file count, per-file and total size, ZIP expansion, path and name lengths, TTL default/maximum, allowed extensions and skipped system files.
459
+ - `publish_site` and `republish_site` describe the backend 1.123.0 site rules: 200 files (was 100), 5 MB per file, 20 MB total, 25 MB per request; 400 for a site limit hit, 413 for an oversized request, too many parts or an overlong file name/path, 422 when no servable file is left; entry resolution and skipped system files. Seventeen tools.
460
+
436
461
  ## 1.11.0 -- 2026-10-21
437
462
 
438
463
  - 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.
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.11.0",
8
+ version: "1.12.0",
9
9
  });
10
10
  const PUBLIC_NAMESPACE = "public";
11
11
  /**
@@ -42,6 +42,12 @@ const DELIVERY_MODE_SCHEMA = z.enum(["path", "subdomain"]).optional().describe("
42
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. " +
43
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. " +
44
44
  "When creation returns an existing publication, it keeps its actual mode and URL.");
45
+ /** Site upload rules shared by publish_site and republish_site; current values come from get_limits. */
46
+ const SITE_LIMITS_TEXT = "Limits (call get_limits for current values): a request is at most 25 MB; a site at most 200 files, 5 MB per file and 20 MB in total; " +
47
+ "each path at most 380 characters. System files (.DS_Store, __MACOSX/ and similar) are skipped and never count; files with an unsupported extension " +
48
+ "or a too-long path are skipped and listed in notices. Entry: `entry`, else root index.html, else the shallowest HTML file. " +
49
+ "Errors: 400 = a site limit exceeded (the message names it and what to do), invalid path or no HTML file; 413 = request over 25 MB, " +
50
+ "too many files and form fields, or a file name/path too long; 422 = no servable file left.";
45
51
  function hostingResponseLines(data) {
46
52
  const fields = ["routingCohort", "deliveryMode", "requestedDeliveryMode", "effectiveDeliveryMode",
47
53
  "deliveryModeMatched", "modeLocked", "hostingVersion", "access", "managementLink"];
@@ -366,7 +372,7 @@ server.tool("get_stats", "Get BrewPage platform-wide usage statistics including
366
372
  ],
367
373
  };
368
374
  });
369
- 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`. Repository defaults: 20 MiB total, 100 files, 5 MiB per file. Use its returned primary link and retain the owner token.", {
375
+ 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`. Use its returned primary link and retain the owner token. " + SITE_LIMITS_TEXT, {
370
376
  deliveryMode: DELIVERY_MODE_SCHEMA,
371
377
  entryContent: z
372
378
  .string()
@@ -477,7 +483,7 @@ server.tool("publish_site", "Publish an HTML site to BrewPage. Single-page: pass
477
483
  content: [{ type: "text", text: lines.join("\n") }],
478
484
  };
479
485
  });
480
- server.tool("republish_site", "Republish (full-replace) an existing multi-file BrewPage site in place at the SAME URL/ID. Requires owner token. The uploaded bundle becomes the complete new file set — files absent from it are removed, new files added, matching files overwritten. Single-page: pass `entryContent`. Multi-page: pass `files` (array of `{path, content}`). Optional `entry` overrides the default `index.html`. Site bundles use repository defaults of 20 MiB total, 100 files, 5 MiB per file; republishing preserves existing expiry.", {
486
+ server.tool("republish_site", "Republish (full-replace) an existing multi-file BrewPage site in place at the SAME URL/ID. Requires owner token. The uploaded bundle becomes the complete new file set — files absent from it are removed, new files added, matching files overwritten. Single-page: pass `entryContent`. Multi-page: pass `files` (array of `{path, content}`). Optional `entry` overrides the default `index.html`. Republishing preserves existing expiry. " + SITE_LIMITS_TEXT, {
481
487
  namespace: z.string().describe("Site namespace"),
482
488
  id: z.string().describe("Site ID"),
483
489
  ownerToken: z
@@ -887,6 +893,30 @@ server.tool("get_kv", "Fetch a value from a BrewPage KV store by namespace, ID,
887
893
  ],
888
894
  };
889
895
  });
896
+ server.tool("get_limits", "Get the current BrewPage upload limits (GET /api/limits, no auth): request size, site file count, per-file and total size, " +
897
+ "ZIP expansion, path and name lengths, TTL default/maximum, allowed file extensions and skipped system files. Sizes are bytes. " +
898
+ "Call it before publishing a large or multi-file site.", {}, async () => {
899
+ const { ok, status, data } = await apiRequest("GET", "/api/limits");
900
+ if (!ok) {
901
+ return {
902
+ content: [
903
+ {
904
+ type: "text",
905
+ text: `Failed to fetch limits (${status}): ${JSON.stringify(data)}`,
906
+ },
907
+ ],
908
+ isError: true,
909
+ };
910
+ }
911
+ return {
912
+ content: [
913
+ {
914
+ type: "text",
915
+ text: `BrewPage upload limits (bytes):\n\n${JSON.stringify(data, null, 2)}`,
916
+ },
917
+ ],
918
+ };
919
+ });
890
920
  server.tool("search_gallery", "Search the BrewPage public gallery. Optional filters: text query, pagination, sort, and 'mine' (owner-scoped, requires owner token).", {
891
921
  q: z.string().optional().describe("Free-text search query"),
892
922
  page: z
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brewpage-mcp",
3
- "version": "1.11.0",
3
+ "version": "1.12.0",
4
4
  "mcpName": "io.github.kochetkov-ma/brewpage-mcp",
5
5
  "description": "MCP server for BrewPage — publish and manage HTML, sites, KV, JSON and files from AI assistants",
6
6
  "type": "module",