brewpage-mcp 1.15.5 → 1.16.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 +17 -13
- package/dist/tools.d.ts +1 -1
- package/dist/tools.js +47 -22
- 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.
|
|
20
|
+
npx -y brewpage-mcp@1.16.0
|
|
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.
|
|
53
|
+
"args": ["-y", "brewpage-mcp@1.16.0"]
|
|
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.
|
|
64
|
+
claude mcp add --transport stdio --scope project brewpage -- npx -y brewpage-mcp@1.16.0
|
|
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.
|
|
78
|
+
"args": ["-y", "brewpage-mcp@1.16.0"]
|
|
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.
|
|
92
|
+
"args": ["-y", "brewpage-mcp@1.16.0"]
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
```
|
|
@@ -97,13 +97,13 @@ Open the Cline MCP settings panel and add:
|
|
|
97
97
|
### Global Install
|
|
98
98
|
|
|
99
99
|
```bash
|
|
100
|
-
npm install -g brewpage-mcp@1.
|
|
100
|
+
npm install -g brewpage-mcp@1.16.0
|
|
101
101
|
brewpage-mcp
|
|
102
102
|
```
|
|
103
103
|
|
|
104
104
|
## Tools
|
|
105
105
|
|
|
106
|
-
Twenty tools are available. Creation returns an owner token; keep it to modify or delete the resource later. Owner tools take `ownerToken`, else `BREWPAGE_OWNER_TOKEN
|
|
106
|
+
Twenty tools are available. Creation returns an owner token; keep it to modify or delete the resource later. Owner tools take `ownerToken`, else `BREWPAGE_OWNER_TOKEN` (local server only). Supported password inputs use `X-Password`. Secrets allowed; likely ones are flagged in notices. For a secret: private namespace + password.
|
|
107
107
|
|
|
108
108
|
| Tool | Purpose |
|
|
109
109
|
|------|---------|
|
|
@@ -130,7 +130,7 @@ Twenty tools are available. Creation returns an owner token; keep it to modify o
|
|
|
130
130
|
|
|
131
131
|
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 is private (a generated `priv-<random>` namespace): unlisted and not indexed; anyone with the link can still open it. `public` lists HTML, sites and files in the gallery and sitemap, so Google, Bing and AI search can find and index them; public pages are served on the brewpage.app domain for the strongest reach (a site always gets its own subdomain). Never put secrets in a public publication. Password-protected publications, JSON and KV are never listed.
|
|
132
132
|
|
|
133
|
-
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`; `secret-detected`
|
|
133
|
+
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`; `secret-detected` prints as `WARNING (code): message`: relay it to the user. A live BrewPage token or manage link in public content (`credential-published`) prints first as `SECURITY ALERT (credential-published): …`: tell the user to remove and reset it; that result is hidden from the gallery, so it prints no `VISIBILITY` line. A minted `manageUrl` prints as `MANAGE LINK (private): …`: give it to the user privately, never publish it. A listed public result prints `VISIBILITY: public, listed. Hide: set_visibility listed=false`. `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.
|
|
134
134
|
|
|
135
135
|
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.
|
|
136
136
|
|
|
@@ -232,7 +232,7 @@ publish_file(url="https://example.com/diagram.png")
|
|
|
232
232
|
|
|
233
233
|
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. The result prints `Title:` (entry page title) after `ID:` when the server derives one.
|
|
234
234
|
|
|
235
|
-
Limits (current values from `get_limits`): a request is at most 25
|
|
235
|
+
Limits (current values from `get_limits`): a request is at most 25 MiB; a site at most 200 files, 5 MiB per file and 20 MiB 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 or password-protected; 413 means the request is over 25 MiB, 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).
|
|
236
236
|
|
|
237
237
|
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`).
|
|
238
238
|
|
|
@@ -382,7 +382,7 @@ search_gallery(mine=true, ownerToken="tok_...", sort="date")
|
|
|
382
382
|
|
|
383
383
|
Delete a BrewPage resource (HTML page, site, KV store, JSON document, or file) using the owner token received at creation.
|
|
384
384
|
|
|
385
|
-
Parameters: `type` (`html` | `site` | `kv` | `json` | `file`), `namespace` (string), `id` (string), `ownerToken` (optional; default `BREWPAGE_OWNER_TOKEN
|
|
385
|
+
Parameters: `type` (`html` | `site` | `kv` | `json` | `file`), `namespace` (string), `id` (string), `ownerToken` (optional; default `BREWPAGE_OWNER_TOKEN`, local server only). Path segments are URL-encoded.
|
|
386
386
|
|
|
387
387
|
Example prompt:
|
|
388
388
|
|
|
@@ -412,7 +412,7 @@ Output: `LISTED: false · link unchanged`.
|
|
|
412
412
|
|
|
413
413
|
Add an owner token to your BrewPage profile (as `publish`) with an `admin` token of that profile (`POST /api/owner-token/bind`). Output: `BOUND …ab12 · 3/20 active`; tokens are never printed in full.
|
|
414
414
|
|
|
415
|
-
Parameters: `token`, `ownerToken` (admin token; optional, default `BREWPAGE_OWNER_TOKEN
|
|
415
|
+
Parameters: `token`, `ownerToken` (admin token; optional, default `BREWPAGE_OWNER_TOKEN`, local server only).
|
|
416
416
|
|
|
417
417
|
---
|
|
418
418
|
|
|
@@ -442,9 +442,9 @@ get_stats()
|
|
|
442
442
|
|
|
443
443
|
### `get_limits`
|
|
444
444
|
|
|
445
|
-
Read the current limits from `GET /api/limits` (no auth;
|
|
445
|
+
Read the current limits from `GET /api/limits` (no auth needed; an owner token goes as `X-Owner-Token`). Always returns `reach`: `profile` only when the owner token is active in a profile, else `token` (also with no token); with a usable owner token also `ownerMaxTtlDays`. Sizes are bytes, TTLs days: `requestMaxBytes`; `html`, `json`, `kv` and `files` max size, counts and TTL default/maximum; `profileMaxTtlDays` (TTL cap for a token in a profile); `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.
|
|
446
446
|
|
|
447
|
-
Parameters:
|
|
447
|
+
Parameters: `ownerToken` (optional; default `BREWPAGE_OWNER_TOKEN`, local server only).
|
|
448
448
|
|
|
449
449
|
Example prompt:
|
|
450
450
|
|
|
@@ -530,6 +530,10 @@ Every publish response includes an **owner token** -- the only credential that a
|
|
|
530
530
|
|
|
531
531
|
## Changelog
|
|
532
532
|
|
|
533
|
+
## 1.16.0 -- 2026-10-29
|
|
534
|
+
|
|
535
|
+
- `get_limits` accepts `ownerToken` (remote `/mcp` gets `reach`/`ownerMaxTtlDays`). Results open with `SECURITY ALERT (credential-published)` when public content holds a live BrewPage token or manage link. Wording: limits reach, local-only env token, MiB.
|
|
536
|
+
|
|
533
537
|
## 1.15.5 -- 2026-10-29
|
|
534
538
|
|
|
535
539
|
- `publish_html` prints the page title (`Title:`) when the server reports one; tool texts state plain size limits; `get_limits` names the per-type limits and the profile TTL cap.
|
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.
|
|
3
|
+
export declare const USER_AGENT = "brewpage-mcp/1.16.0";
|
|
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.
|
|
4
|
+
export const USER_AGENT = "brewpage-mcp/1.16.0";
|
|
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 };
|
|
@@ -10,15 +10,21 @@ const ADDITIVE = { readOnlyHint: false, destructiveHint: false };
|
|
|
10
10
|
function toolMeta(title, hints) {
|
|
11
11
|
return { title, annotations: { title, ...hints } };
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
13
|
+
/** Env default exists only in the local (stdio) server; remote /mcp takes ownerToken per call. */
|
|
14
|
+
const ENV_DEFAULT = `env ${OWNER_TOKEN_ENV} (local server only)`;
|
|
15
|
+
const NO_OWNER_TOKEN = `No owner token: pass ownerToken (local server: or set ${OWNER_TOKEN_ENV}).`;
|
|
16
|
+
const CREATE_OWNER_TOKEN_DESCRIPTION = `Optional. Default: ${ENV_DEFAULT}, else a new token per create.`;
|
|
17
|
+
const OWNER_TOKEN_DESCRIPTION = `Owner token from create. Default: ${ENV_DEFAULT}.`;
|
|
18
|
+
const SECRETS = "Secrets allowed; likely ones are flagged in notices. Private namespace + password suit secrets. " +
|
|
19
|
+
"BrewPage tokens and manage links must never be in public content.";
|
|
17
20
|
const MANAGE_URL_TEXT = "Returns manageUrl, a private management link (grants control; not for public sharing).";
|
|
18
21
|
const OLD_READ_ONLY_CODE = "OLD_PUBLICATION_READ_ONLY";
|
|
19
22
|
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.`;
|
|
20
23
|
/** Notice codes the agent must relay to the user. */
|
|
21
|
-
const WARNING_CODES = new Set(["secret-detected"
|
|
24
|
+
const WARNING_CODES = new Set(["secret-detected"]);
|
|
25
|
+
/** Live BrewPage token or manage link in public content: printed first as a security alert, never listed. */
|
|
26
|
+
const CREDENTIAL_CODE = "credential-published";
|
|
27
|
+
const CREDENTIAL_ALERT_TAIL = "Tell the user now: anyone with this link can use that token; they must remove it and reset it.";
|
|
22
28
|
/** MCP type name -> REST path segment. */
|
|
23
29
|
const TYPE_SEGMENTS = { html: "html", site: "sites", file: "files", json: "json", kv: "kv" };
|
|
24
30
|
/** `/api/<segments>` with each segment encoded; empty, `.` and `..` refused (URL parsing would resolve them away). */
|
|
@@ -108,11 +114,11 @@ const DELIVERY_MODE_SCHEMA = z.enum(["path", "subdomain"]).optional().describe("
|
|
|
108
114
|
"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. " +
|
|
109
115
|
"When creation returns an existing publication, it keeps its actual mode and URL.");
|
|
110
116
|
/** Site upload rules shared by publish_site and republish_site; current values come from get_limits. */
|
|
111
|
-
const SITE_LIMITS_TEXT = "Default limits (current values: GET /api/limits): a request is at most 25
|
|
117
|
+
const SITE_LIMITS_TEXT = "Default limits (current values: GET /api/limits): a request is at most 25 MiB; a site at most 200 files, 5 MiB per file and 20 MiB in total; " +
|
|
112
118
|
"each path at most 380 characters. System files (.DS_Store, __MACOSX/ and similar) are skipped and never count; files with an unsupported extension " +
|
|
113
119
|
"or a too-long path are skipped and listed in notices. Entry: `entry`, else root index.html, else the shallowest HTML file. " +
|
|
114
120
|
"Errors: 400 = a site limit exceeded (the message names it), invalid path, no HTML file, or a PDF/Office file unreadable " +
|
|
115
|
-
"or password-protected; 413 = request over 25
|
|
121
|
+
"or password-protected; 413 = request over 25 MiB, too many files and form fields, or a file name/path too long; " +
|
|
116
122
|
"422 = no servable file left; 503 = busy, retry after Retry-After seconds.";
|
|
117
123
|
function hostingResponseLines(data) {
|
|
118
124
|
const fields = ["routingCohort", "deliveryMode", "requestedDeliveryMode", "effectiveDeliveryMode",
|
|
@@ -126,14 +132,26 @@ function hostingResponseLines(data) {
|
|
|
126
132
|
lines.push(...noticeLines(data));
|
|
127
133
|
return lines;
|
|
128
134
|
}
|
|
129
|
-
/** Server `notices` ({code, message}) on publish/update responses
|
|
130
|
-
function
|
|
135
|
+
/** Server `notices` ({code, message}) on publish/update responses, well-formed only. */
|
|
136
|
+
function notices(data) {
|
|
131
137
|
if (!Array.isArray(data.notices))
|
|
132
138
|
return [];
|
|
133
|
-
return data.notices
|
|
134
|
-
|
|
139
|
+
return data.notices.filter((n) => typeof n === "object" && n !== null && typeof n.code === "string" && typeof n.message === "string");
|
|
140
|
+
}
|
|
141
|
+
/** Each tolerated-input adjustment, verbatim; the credential alert prints separately, first. */
|
|
142
|
+
function noticeLines(data) {
|
|
143
|
+
return notices(data).filter((n) => n.code !== CREDENTIAL_CODE)
|
|
135
144
|
.map((n) => `${WARNING_CODES.has(n.code) ? "WARNING" : "Notice"} (${n.code}): ${n.message}`);
|
|
136
145
|
}
|
|
146
|
+
function hasCredentialNotice(data) {
|
|
147
|
+
return notices(data).some((n) => n.code === CREDENTIAL_CODE);
|
|
148
|
+
}
|
|
149
|
+
/** Opening lines of a result whose public content holds a live BrewPage credential, else none. */
|
|
150
|
+
function credentialAlertLines(data) {
|
|
151
|
+
const alerts = notices(data).filter((n) => n.code === CREDENTIAL_CODE)
|
|
152
|
+
.map((n) => `SECURITY ALERT (${CREDENTIAL_CODE}): ${n.message} ${CREDENTIAL_ALERT_TAIL}`);
|
|
153
|
+
return alerts.length ? [...alerts, ``] : [];
|
|
154
|
+
}
|
|
137
155
|
const SIGN_IN_HINT = "Optional: sign in free (Google or any email) at https://account.brewpage.app to never lose your pages or tokens and to mint tokens that never expire. Not needed to publish.";
|
|
138
156
|
/** Private management link (present only when minted) and the public listing state. */
|
|
139
157
|
function ownerLinkLines(data) {
|
|
@@ -141,7 +159,7 @@ function ownerLinkLines(data) {
|
|
|
141
159
|
if (typeof data.manageUrl === "string" && data.manageUrl.length > 0) {
|
|
142
160
|
lines.push(``, `MANAGE LINK (private): ${data.manageUrl}`, `Give it to the user privately; never publish it.`);
|
|
143
161
|
}
|
|
144
|
-
if (data.listed === true)
|
|
162
|
+
if (data.listed === true && !hasCredentialNotice(data))
|
|
145
163
|
lines.push(``, `VISIBILITY: public, listed. Hide: set_visibility listed=false`);
|
|
146
164
|
return lines;
|
|
147
165
|
}
|
|
@@ -157,6 +175,7 @@ function deliveryReasonLines(data) {
|
|
|
157
175
|
}
|
|
158
176
|
function formatUpdateResponse(data) {
|
|
159
177
|
const lines = [
|
|
178
|
+
...credentialAlertLines(data),
|
|
160
179
|
`Updated successfully!`,
|
|
161
180
|
``,
|
|
162
181
|
`URL: ${data.link || data.url || "N/A"}`,
|
|
@@ -188,7 +207,7 @@ export function createServer(options = {}) {
|
|
|
188
207
|
const apiFetch = options.fetch ?? fetch;
|
|
189
208
|
const server = new McpServer({
|
|
190
209
|
name: "brewpage-mcp",
|
|
191
|
-
version: "1.
|
|
210
|
+
version: "1.16.0",
|
|
192
211
|
});
|
|
193
212
|
/** Caller argument first, then the configured default; `fromEnv` marks the configured one. */
|
|
194
213
|
function ownerTokenFor(argument) {
|
|
@@ -242,6 +261,7 @@ export function createServer(options = {}) {
|
|
|
242
261
|
}
|
|
243
262
|
function formatPublishResponse(data, effectiveNamespace, sentOwnerToken, listable = true) {
|
|
244
263
|
const lines = [
|
|
264
|
+
...credentialAlertLines(data),
|
|
245
265
|
`Published successfully!`,
|
|
246
266
|
``,
|
|
247
267
|
`URL: ${data.link || data.url || "N/A"}`,
|
|
@@ -595,6 +615,7 @@ export function createServer(options = {}) {
|
|
|
595
615
|
}
|
|
596
616
|
const site = data;
|
|
597
617
|
const lines = [
|
|
618
|
+
...credentialAlertLines(site),
|
|
598
619
|
`Site published successfully!`,
|
|
599
620
|
``,
|
|
600
621
|
`URL: ${site.link || "N/A"}`,
|
|
@@ -687,6 +708,7 @@ export function createServer(options = {}) {
|
|
|
687
708
|
return ownerFailure("republish site", res.status, data, auth.fromEnv, res.headers);
|
|
688
709
|
const site = data;
|
|
689
710
|
const lines = [
|
|
711
|
+
...credentialAlertLines(site),
|
|
690
712
|
`Site republished successfully (full replace)!`,
|
|
691
713
|
``,
|
|
692
714
|
`URL: ${site.link || "N/A"}`,
|
|
@@ -1014,10 +1036,13 @@ export function createServer(options = {}) {
|
|
|
1014
1036
|
description: "Get the current BrewPage limits (GET /api/limits): request size; per type (html, json, kv, files, sites) max size, " +
|
|
1015
1037
|
"counts and TTL default/maximum; profileMaxTtlDays (TTL cap for a token in a profile); site ZIP expansion, path and name lengths, " +
|
|
1016
1038
|
"allowed file extensions and skipped system files. Sizes are bytes, TTLs days. " +
|
|
1017
|
-
`
|
|
1018
|
-
inputSchema: {
|
|
1019
|
-
|
|
1020
|
-
|
|
1039
|
+
`The answer always has reach: \`profile\` only when the owner token is active in a profile, else \`token\` (also with no token). With a usable owner token also ownerMaxTtlDays.`,
|
|
1040
|
+
inputSchema: {
|
|
1041
|
+
ownerToken: z.string().optional().describe(OWNER_TOKEN_DESCRIPTION),
|
|
1042
|
+
},
|
|
1043
|
+
}, async ({ ownerToken }) => {
|
|
1044
|
+
const { token } = ownerTokenFor(ownerToken);
|
|
1045
|
+
const headers = token ? { "X-Owner-Token": token } : {};
|
|
1021
1046
|
const { ok, status, data } = await apiRequest("GET", "/api/limits", undefined, headers);
|
|
1022
1047
|
if (!ok) {
|
|
1023
1048
|
return {
|
|
@@ -1068,7 +1093,7 @@ export function createServer(options = {}) {
|
|
|
1068
1093
|
ownerToken: z
|
|
1069
1094
|
.string()
|
|
1070
1095
|
.optional()
|
|
1071
|
-
.describe(`Owner token; only sent as X-Owner-Token when 'mine' is true. Default: ${
|
|
1096
|
+
.describe(`Owner token; only sent as X-Owner-Token when 'mine' is true. Default: ${ENV_DEFAULT}.`),
|
|
1072
1097
|
},
|
|
1073
1098
|
}, async ({ q, page, size, sort, mine, ownerToken }) => {
|
|
1074
1099
|
const auth = ownerTokenFor(ownerToken);
|
|
@@ -1119,14 +1144,14 @@ export function createServer(options = {}) {
|
|
|
1119
1144
|
if (!ok)
|
|
1120
1145
|
return ownerFailure("set visibility", status, data, auth.fromEnv);
|
|
1121
1146
|
const result = data;
|
|
1122
|
-
return textResult([`LISTED: ${result.listed} · link unchanged`, ...noticeLines(result)].join("\n"));
|
|
1147
|
+
return textResult([...credentialAlertLines(result), `LISTED: ${result.listed} · link unchanged`, ...noticeLines(result)].join("\n"));
|
|
1123
1148
|
});
|
|
1124
1149
|
server.registerTool("bind_token", {
|
|
1125
1150
|
...toolMeta("Add token to profile", ADDITIVE),
|
|
1126
1151
|
description: "Add an owner token to your BrewPage profile (as publish). Needs an admin token of that profile.",
|
|
1127
1152
|
inputSchema: {
|
|
1128
1153
|
token: z.string().describe("Owner token to add"),
|
|
1129
|
-
ownerToken: z.string().optional().describe(`Admin token of the profile. Default: ${
|
|
1154
|
+
ownerToken: z.string().optional().describe(`Admin token of the profile. Default: ${ENV_DEFAULT}.`),
|
|
1130
1155
|
},
|
|
1131
1156
|
}, async ({ token, ownerToken }) => {
|
|
1132
1157
|
const auth = ownerTokenFor(ownerToken);
|
|
@@ -1145,7 +1170,7 @@ export function createServer(options = {}) {
|
|
|
1145
1170
|
label: z.string().optional().describe("Optional label shown in the profile"),
|
|
1146
1171
|
scope: z.enum(["publish", "admin"]).optional().describe("publish (default) or admin (can manage tokens)"),
|
|
1147
1172
|
expiresIn: z.enum(["30d", "90d", "1y", "never"]).optional().describe("Default: admin 90d, publish never"),
|
|
1148
|
-
ownerToken: z.string().optional().describe(`Admin token of the profile. Default: ${
|
|
1173
|
+
ownerToken: z.string().optional().describe(`Admin token of the profile. Default: ${ENV_DEFAULT}.`),
|
|
1149
1174
|
},
|
|
1150
1175
|
}, async ({ label, scope, expiresIn, ownerToken }) => {
|
|
1151
1176
|
const auth = ownerTokenFor(ownerToken);
|
package/package.json
CHANGED