@page2ai/mcp 0.5.3 → 0.6.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/CHANGELOG.md CHANGED
@@ -5,6 +5,33 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
5
5
  project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html); while the
6
6
  major version is `0`, a minor bump may carry breaking changes.
7
7
 
8
+ ## 0.6.0 - 2026-10-24
9
+
10
+ ### Security
11
+
12
+ - **Agent Bridge pairs with a key (protocol `page2ai-bridge/2`).** Any local program could listen on port 3025 while no server ran, and the extension obeyed its `convert` with the user's signed-in browser; a program could also connect to the server under a forged `Origin`. The extension now makes a key, the user pastes it into `PAGE2AI_BRIDGE_KEY` (in the `.mcpb`: the *Agent Bridge key* setting), and on every connection both sides prove they know it with HMAC-SHA256 over two nonces and the port, the server first. Without a key the server connects no browser and says so in its log. A connection takes the single slot only after the proof; at most 4 wait in the handshake, 5 s each. Breaking: extensions speaking `page2ai-bridge/1` get `PROTOCOL_MISMATCH` (no released extension does).
13
+
14
+ ### Changed
15
+
16
+ - **Firefox needs no origin setting.** Any `moz-extension://` origin may start the handshake and the key admits Page2AI; `PAGE2AI_BRIDGE_ORIGINS` remains for unpacked Chrome builds.
17
+ - The per-session token of `page2ai-bridge/1` is gone: the authenticated connection is the session.
18
+
19
+ ## 0.5.4 - 2026-10-23
20
+
21
+ ### Security
22
+
23
+ - **Agent Bridge keeps the SSRF guard.** The tool's description says private ranges, loopback and cloud metadata endpoints are blocked, and the server's own fetch blocks them; 0.5.0 to 0.5.3 sent such a URL to the extension, which opened it in the user's browser (`http://192.168.1.1/`, `http://169.254.169.254/…`, a name resolving to `10.x`). The server now checks the URL with the same guard, DNS included, before the browser opens it, and refuses a result whose page, after a redirect the browser followed, is at a blocked address. A name this server cannot resolve still goes to the browser, which may reach it through a proxy.
24
+
25
+ ### Fixed
26
+
27
+ - **A blank bridge result, or one from a page that is not a web address, is refused** (`BAD_RESULT`) and answered by the server's fetch. 0.5.3 refused a missing `markdown` but returned `""` as the page, and Firefox reports a new tab's `about:blank` complete before the page loads.
28
+ - **The server exits when stdin closes even while a client is connected that never answers.** 0.5.3 waited for the WebSocket close handshake, up to 30 s; `scripts/stdin-exit.mjs` now connects such a client first, and the process ends at most 3 s after stdin closes.
29
+ - **No `provenance` line inside the text when frontmatter is off.** HTML that opens with `<hr>` renders as `---`, and 0.5.3 inserted the line into the page's text under `include_frontmatter: false`.
30
+
31
+ ### Changed
32
+
33
+ - **A redirect on the same host is reported too**: a sign-in page at another path, or another port. An http-to-https upgrade, a trailing slash or a changed query is not.
34
+
8
35
  ## 0.5.3 - 2026-10-23
9
36
 
10
37
  ### Security
package/README.md CHANGED
@@ -176,14 +176,26 @@ The server fetches without cookies and runs no page scripts. For a page that nee
176
176
  extension's Markdown (its own output settings apply, not `include_images` /
177
177
  `include_frontmatter`). The extension refuses sign-in providers' pages and anything that is
178
178
  not http(s); a page it refuses is fetched by the server as usual, with a second text block
179
- saying why; when the browser ends on another host (a sign-in redirect), a second text block
180
- names the page it got. The bridge listens on `ws://127.0.0.1:3025` only. In Chrome it accepts
181
- the Page2AI extension alone (its Web Store ID). Firefox gives each install a random origin, so
182
- a Firefox install is accepted only by its exact origin listed in `PAGE2AI_BRIDGE_ORIGINS`
183
- (Firefox shows it at `about:debugging#/runtime/this-firefox` as the extension's Internal UUID:
184
- `moz-extension://<that UUID>`); 0.5.0 to 0.5.2 accepted any Firefox extension. The origin check
185
- stops web pages and other browser extensions; another program on the same computer can claim
186
- any origin, so the bridge is no stronger than your user account.
179
+ saying why; when the browser ends on another page (a sign-in redirect), a second text block
180
+ names the page it got. Private, loopback and cloud metadata addresses are refused before the
181
+ browser opens them, as by the server's own fetch, and so is a page the browser was redirected
182
+ to at one. The bridge listens on `ws://127.0.0.1:3025` only.
183
+
184
+ **The key (0.6.0 and later).** The bridge works only with the key the extension shows: popup →
185
+ *Agent Bridge* on → *Copy key*. Give it to this server as `PAGE2AI_BRIDGE_KEY`: in Claude Desktop
186
+ (the `.mcpb` extension) paste it into Page2AI's setting *Agent Bridge key*; in a JSON config add
187
+ `"env": { "PAGE2AI_BRIDGE_KEY": "<key>" }` to the server entry; with Claude Code,
188
+ `claude mcp add page2ai -e PAGE2AI_BRIDGE_KEY=<key> -- npx -y @page2ai/mcp`. Restart the MCP
189
+ client after. Several browsers or profiles: put their keys in the one variable, separated by
190
+ commas; the first to connect holds the bridge. Without a key the server never sends a page to a
191
+ browser, and the popup and this server's log say what to paste where. On every connection both
192
+ sides prove they know the key (an HMAC exchange; the key never crosses the socket), the server
193
+ first: a program that took port 3025 while no server ran gets nothing from the extension, and a
194
+ program that connects to the server without the key cannot ask it for pages. Firefox needs no
195
+ extra setting since 0.6.0 (0.5.3 required the install's UUID in `PAGE2AI_BRIDGE_ORIGINS`).
196
+ *New key* in the popup, or reinstalling the extension, makes a new key: paste it again.
197
+ Whoever reads your MCP client's config or the browser profile can read the key: the bridge is
198
+ no stronger than your user account.
187
199
 
188
200
  ## Example prompts
189
201
 
@@ -251,12 +263,13 @@ No setup required — every argument has a sensible default. `page_to_markdown`
251
263
  The hosted endpoint takes `url` only (the contract its ChatGPT plugin was reviewed with) and
252
264
  caps `timeout_ms` at 20000.
253
265
 
254
- Environment variables of the local server, both optional:
266
+ Environment variables of the local server, all optional:
255
267
 
256
268
  | Variable | Default | Effect |
257
269
  |---|---|---|
270
+ | `PAGE2AI_BRIDGE_KEY` | — | The Agent Bridge key(s) from the Page2AI popup, comma-separated. Without one the bridge connects no browser |
258
271
  | `PAGE2AI_BRIDGE_PORT` | `3025` | Port of the Agent Bridge on 127.0.0.1. If it is taken (another running instance), the server starts without the bridge |
259
- | `PAGE2AI_BRIDGE_ORIGINS` | — | Exact extension origins the bridge accepts besides Page2AI's Web Store ID, comma-separated: a Firefox install's `moz-extension://<uuid>`, an unpacked build's `chrome-extension://<id>` |
272
+ | `PAGE2AI_BRIDGE_ORIGINS` | — | Exact origins of unpacked or self-built Chrome builds the bridge accepts besides Page2AI's Web Store ID, comma-separated (`chrome-extension://<id>`). Firefox needs none |
260
273
 
261
274
  Planned: a `profile` argument (`auto | docs | marketing | research | dashboard | wordpress-marketing`).
262
275
 
@@ -0,0 +1,22 @@
1
+ export declare const BRIDGE_KEY_ENV = "PAGE2AI_BRIDGE_KEY";
2
+ export interface BridgeKey {
3
+ /** First 16 hex digits of SHA-256(key): names the key in hello and in logs. */
4
+ id: string;
5
+ bytes: Buffer;
6
+ }
7
+ export declare const keyIdOf: (bytes: Buffer) => string;
8
+ /** Reads PAGE2AI_BRIDGE_KEY. Tolerates what a copy-paste brings along (spaces,
9
+ * quotes, the variable's own name before `=`); an MCPB field left empty may arrive
10
+ * unexpanded and counts as no key. A bad entry is reported by its position, never
11
+ * by its value: the log goes to the MCP client's files. */
12
+ export declare const parseBridgeKeys: (raw: string | undefined) => {
13
+ keys: BridgeKey[];
14
+ problems: string[];
15
+ };
16
+ export declare const isHex64: (v: unknown) => v is string;
17
+ /** What the server sends: it knows the key, on this port, for this hello. */
18
+ export declare const serverProof: (key: Buffer, port: number, nonceE: string, nonceS: string) => string;
19
+ /** What the extension sends back once the server's proof checked out. */
20
+ export declare const clientProof: (key: Buffer, port: number, nonceS: string, nonceE: string) => string;
21
+ export declare const proofMatches: (expected: string, got: unknown) => boolean;
22
+ //# sourceMappingURL=keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/bridge/keys.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,cAAc,uBAAuB,CAAC;AAEnD,MAAM,WAAW,SAAS;IACxB,+EAA+E;IAC/E,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAMD,eAAO,MAAM,OAAO,GAAI,OAAO,MAAM,KAAG,MACuB,CAAC;AAEhE;;;4DAG4D;AAC5D,eAAO,MAAM,eAAe,GAAI,KAAK,MAAM,GAAG,SAAS,KAAG;IAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAkBhG,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,GAAG,OAAO,KAAG,CAAC,IAAI,MAAgD,CAAC;AAK3F,6EAA6E;AAC7E,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,EAAE,MAAM,MAAM,EAAE,QAAQ,MAAM,EAAE,QAAQ,MAAM,KAAG,MACjB,CAAC;AAExE,yEAAyE;AACzE,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,EAAE,MAAM,MAAM,EAAE,QAAQ,MAAM,EAAE,QAAQ,MAAM,KAAG,MACjB,CAAC;AAExE,eAAO,MAAM,YAAY,GAAI,UAAU,MAAM,EAAE,KAAK,OAAO,KAAG,OAC0B,CAAC"}
@@ -0,0 +1,45 @@
1
+ // Agent Bridge keys. The Page2AI extension makes one (32 random bytes, base64url,
2
+ // shown in its popup) and the user pastes it into this server's PAGE2AI_BRIDGE_KEY;
3
+ // several keys, one per browser profile, are separated by commas. Both ends then
4
+ // prove they know it (protocol.ts); the key itself never crosses the socket.
5
+ import { createHash, createHmac, timingSafeEqual } from 'node:crypto';
6
+ import { BRIDGE_PROTOCOL } from './protocol.js';
7
+ export const BRIDGE_KEY_ENV = 'PAGE2AI_BRIDGE_KEY';
8
+ // 32 bytes in base64url: 43 characters, padding optional.
9
+ const KEY_PATTERN = /^[A-Za-z0-9_-]{43}=?$/;
10
+ const HEX64 = /^[0-9a-f]{64}$/;
11
+ export const keyIdOf = (bytes) => createHash('sha256').update(bytes).digest('hex').slice(0, 16);
12
+ /** Reads PAGE2AI_BRIDGE_KEY. Tolerates what a copy-paste brings along (spaces,
13
+ * quotes, the variable's own name before `=`); an MCPB field left empty may arrive
14
+ * unexpanded and counts as no key. A bad entry is reported by its position, never
15
+ * by its value: the log goes to the MCP client's files. */
16
+ export const parseBridgeKeys = (raw) => {
17
+ const keys = [];
18
+ const problems = [];
19
+ const entries = (raw ?? '').split(',');
20
+ entries.forEach((entry, i) => {
21
+ let s = entry.trim().replace(/^["']+|["']+$/g, '').trim();
22
+ if (s.startsWith(`${BRIDGE_KEY_ENV}=`))
23
+ s = s.slice(BRIDGE_KEY_ENV.length + 1).trim();
24
+ if (s === '' || s.includes('${'))
25
+ return;
26
+ if (!KEY_PATTERN.test(s)) {
27
+ problems.push(`entry ${i + 1} of ${entries.length} is not a Page2AI key ` +
28
+ `(${s.length} characters; a key from the extension's popup has 43)`);
29
+ return;
30
+ }
31
+ const bytes = Buffer.from(s.replace(/=$/, ''), 'base64url');
32
+ const id = keyIdOf(bytes);
33
+ if (!keys.some((k) => k.id === id))
34
+ keys.push({ id, bytes });
35
+ });
36
+ return { keys, problems };
37
+ };
38
+ export const isHex64 = (v) => typeof v === 'string' && HEX64.test(v);
39
+ const proofOf = (key, text) => createHmac('sha256', key).update(text).digest('hex');
40
+ /** What the server sends: it knows the key, on this port, for this hello. */
41
+ export const serverProof = (key, port, nonceE, nonceS) => proofOf(key, `${BRIDGE_PROTOCOL}|server|${port}|${nonceE}|${nonceS}`);
42
+ /** What the extension sends back once the server's proof checked out. */
43
+ export const clientProof = (key, port, nonceS, nonceE) => proofOf(key, `${BRIDGE_PROTOCOL}|client|${port}|${nonceS}|${nonceE}`);
44
+ export const proofMatches = (expected, got) => isHex64(got) && timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(got, 'hex'));
45
+ //# sourceMappingURL=keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/bridge/keys.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- export declare const BRIDGE_PROTOCOL = "page2ai-bridge/1";
1
+ export declare const BRIDGE_PROTOCOL = "page2ai-bridge/2";
2
2
  export declare const DEFAULT_BRIDGE_PORT = 3025;
3
3
  /** A bridge failure with the protocol's code (TIMEOUT, PERMISSION_REQUIRED, ...).
4
4
  * Callers decide by `code`; the message is for people and may change. */
@@ -8,18 +8,24 @@ export declare class BridgeError extends Error {
8
8
  }
9
9
  export interface HelloMessage {
10
10
  type: 'hello';
11
- protocol: typeof BRIDGE_PROTOCOL;
11
+ protocol: string;
12
12
  extensionId: string;
13
13
  extensionVersion: string;
14
+ /** First 16 hex digits of SHA-256(key): which of the server's keys to use. */
15
+ keyId: string;
16
+ /** 32 random bytes, hex. */
17
+ nonceE: string;
18
+ }
19
+ export interface AuthMessage {
20
+ type: 'auth';
21
+ proof: string;
14
22
  }
15
23
  export interface PingMessage {
16
24
  type: 'ping';
17
- token: string;
18
25
  }
19
26
  export interface ConvertResultMessage {
20
27
  type: 'result';
21
28
  id: string;
22
- token: string;
23
29
  markdown: string;
24
30
  title: string;
25
31
  url: string;
@@ -29,21 +35,30 @@ export interface ConvertResultMessage {
29
35
  export interface ConvertErrorMessage {
30
36
  type: 'error';
31
37
  id: string;
32
- token: string;
33
38
  code: 'TAB_LOAD_FAILED' | 'EXTRACTION_FAILED' | 'TIMEOUT' | 'RESTRICTED_URL' | 'PERMISSION_REQUIRED';
34
39
  message: string;
35
40
  }
36
- export type ExtensionMessage = HelloMessage | PingMessage | ConvertResultMessage | ConvertErrorMessage;
41
+ export type ExtensionMessage = HelloMessage | AuthMessage | PingMessage | ConvertResultMessage | ConvertErrorMessage;
42
+ export interface ChallengeMessage {
43
+ type: 'challenge';
44
+ protocol: typeof BRIDGE_PROTOCOL;
45
+ serverVersion: string;
46
+ /** 32 random bytes, hex. */
47
+ nonceS: string;
48
+ proof: string;
49
+ }
37
50
  export interface WelcomeMessage {
38
51
  type: 'welcome';
39
52
  protocol: typeof BRIDGE_PROTOCOL;
40
53
  serverVersion: string;
41
- token: string;
42
54
  }
55
+ /** Before the handshake ends: NO_KEY, UNKNOWN_KEY, PROTOCOL_MISMATCH (with the
56
+ * server's `protocol`), AUTH_FAILED, ALREADY_CONNECTED. */
43
57
  export interface ServerErrorMessage {
44
58
  type: 'error';
45
59
  code: string;
46
60
  message: string;
61
+ protocol?: string;
47
62
  }
48
63
  export interface ConvertRequestMessage {
49
64
  type: 'convert';
@@ -58,7 +73,7 @@ export interface ConvertRequestMessage {
58
73
  export interface PongMessage {
59
74
  type: 'pong';
60
75
  }
61
- export type ServerMessage = WelcomeMessage | ServerErrorMessage | ConvertRequestMessage | PongMessage;
76
+ export type ServerMessage = ChallengeMessage | WelcomeMessage | ServerErrorMessage | ConvertRequestMessage | PongMessage;
62
77
  export interface BridgeConvertOptions {
63
78
  url: string;
64
79
  includeImages: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/bridge/protocol.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,qBAAqB,CAAC;AAClD,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAExC;0EAC0E;AAC1E,qBAAa,WAAY,SAAQ,KAAK;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAK1C;AAID,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,OAAO,eAAe,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,QAAQ,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IAGd,IAAI,EAAE,iBAAiB,GAAG,mBAAmB,GAAG,SAAS,GAAG,gBAAgB,GAAG,qBAAqB,CAAC;IACrG,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,WAAW,GAAG,oBAAoB,GAAG,mBAAmB,CAAC;AAIvG,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,OAAO,eAAe,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,SAAS,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE;QACP,aAAa,EAAE,OAAO,CAAC;QACvB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,aAAa,GAAG,cAAc,GAAG,kBAAkB,GAAG,qBAAqB,GAAG,WAAW,CAAC;AAItG,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,OAAO,CAAC;IACvB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/bridge/protocol.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,16 @@
1
1
  // Agent Bridge WebSocket protocol types.
2
2
  // Transport: JSON text frames over ws://127.0.0.1:PORT.
3
- // Security model: BrowserTools MCP v2.0 (post GHSA-xvrv-w8pg-f25f).
4
- export const BRIDGE_PROTOCOL = 'page2ai-bridge/1';
3
+ //
4
+ // page2ai-bridge/2 (0.6.0): both ends prove they know a key the extension made and
5
+ // the user pasted into this server's PAGE2AI_BRIDGE_KEY, before anything else runs.
6
+ // ext → srv hello {keyId, nonceE}
7
+ // srv → ext challenge {nonceS, proof: HMAC(key, "page2ai-bridge/2|server|<port>|<nonceE>|<nonceS>")}
8
+ // ext → srv auth {proof: HMAC(key, "page2ai-bridge/2|client|<port>|<nonceS>|<nonceE>")}
9
+ // srv → ext welcome
10
+ // The extension checks the server's proof before it sends its own and before it
11
+ // accepts any convert: a program that took the port without the key gets nothing.
12
+ // The port is inside both proofs, so a relay through another port fails.
13
+ export const BRIDGE_PROTOCOL = 'page2ai-bridge/2';
5
14
  export const DEFAULT_BRIDGE_PORT = 3025;
6
15
  /** A bridge failure with the protocol's code (TIMEOUT, PERMISSION_REQUIRED, ...).
7
16
  * Callers decide by `code`; the message is for people and may change. */
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/bridge/protocol.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,wDAAwD;AACxD,oEAAoE;AAEpE,MAAM,CAAC,MAAM,eAAe,GAAG,kBAAkB,CAAC;AAClD,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAExC;0EAC0E;AAC1E,MAAM,OAAO,WAAY,SAAQ,KAAK;IAC3B,IAAI,CAAS;IAEtB,YAAY,IAAY,EAAE,OAAe;QACvC,KAAK,CAAC,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/bridge/protocol.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,wDAAwD;AACxD,EAAE;AACF,mFAAmF;AACnF,oFAAoF;AACpF,0CAA0C;AAC1C,yGAAyG;AACzG,iGAAiG;AACjG,uBAAuB;AACvB,gFAAgF;AAChF,kFAAkF;AAClF,yEAAyE;AAEzE,MAAM,CAAC,MAAM,eAAe,GAAG,kBAAkB,CAAC;AAClD,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAExC;0EAC0E;AAC1E,MAAM,OAAO,WAAY,SAAQ,KAAK;IAC3B,IAAI,CAAS;IAEtB,YAAY,IAAY,EAAE,OAAe;QACvC,KAAK,CAAC,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
@@ -1,4 +1,5 @@
1
1
  import { type BridgeConvertOptions, type BridgeConvertResult } from './protocol.js';
2
+ import { type BridgeKey } from './keys.js';
2
3
  /** Page2AI's Chrome Web Store ID: Chrome, Edge and the other Chromium browsers
3
4
  * that install from the store send this Origin. */
4
5
  export declare const PAGE2AI_CHROME_ORIGIN = "chrome-extension://dlpaaijcnbbmlfeohlphjpnbbcnomnno";
@@ -6,20 +7,27 @@ export declare class BridgeServer {
6
7
  private httpServer;
7
8
  private wss;
8
9
  private client;
9
- private sessionToken;
10
+ private handshakes;
10
11
  private pending;
11
12
  private requestCounter;
12
13
  private readonly port;
13
14
  private readonly serverVersion;
14
15
  private readonly log;
15
16
  private readonly extraOrigins;
17
+ private readonly keys;
18
+ private readonly handshakeMs;
16
19
  constructor(opts: {
17
20
  port?: number;
18
21
  serverVersion: string;
19
22
  log: (msg: string) => void;
20
23
  /** Exact origins accepted beside the store's, e.g. an unpacked build's. */
21
24
  extraOrigins?: readonly string[];
25
+ /** From PAGE2AI_BRIDGE_KEY (keys.ts). None: the bridge answers NO_KEY. */
26
+ keys?: readonly BridgeKey[];
27
+ /** How long a socket may take to finish the handshake (tests shorten it). */
28
+ handshakeMs?: number;
22
29
  });
30
+ /** An extension that passed the handshake holds the connection. */
23
31
  isConnected(): boolean;
24
32
  start(): Promise<void>;
25
33
  stop(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/bridge/server.ts"],"names":[],"mappings":"AAcA,OAAO,EAIL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EAMzB,MAAM,eAAe,CAAC;AAEvB;oDACoD;AACpD,eAAO,MAAM,qBAAqB,wDAAwD,CAAC;AAQ3F,qBAAa,YAAY;IACvB,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,GAAG,CAAgC;IAC3C,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAwB;IAC5C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoB;gBAErC,IAAI,EAAE;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;QACtB,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAC3B,2EAA2E;QAC3E,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;KAClC;IAOD,WAAW,IAAI,OAAO;IAIhB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAqDtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBrB,OAAO,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA4BvE,OAAO,CAAC,aAAa;IA2BrB,OAAO,CAAC,gBAAgB;CAqHzB"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/bridge/server.ts"],"names":[],"mappings":"AAiBA,OAAO,EAIL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EAMzB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAmE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAE5G;oDACoD;AACpD,eAAO,MAAM,qBAAqB,wDAAwD,CAAC;AA2B3F,qBAAa,YAAY;IACvB,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,GAAG,CAAgC;IAC3C,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAwB;IAC5C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoB;IACjD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAuB;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,IAAI,EAAE;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;QACtB,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAC3B,2EAA2E;QAC3E,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QACjC,0EAA0E;QAC1E,IAAI,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;QAC5B,6EAA6E;QAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB;IASD,mEAAmE;IACnE,WAAW,IAAI,OAAO;IAIhB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA6DtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA2BrB,OAAO,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA4BvE,OAAO,CAAC,aAAa;IAyBrB,OAAO,CAAC,gBAAgB;CA8JzB"}
@@ -2,36 +2,61 @@
2
2
  // to the Page2AI browser extension for extraction through the user's real
3
3
  // browser (cookies, JS rendering, extension-quality Markdown).
4
4
  //
5
- // Security model (BrowserTools MCP v2.0, post GHSA-xvrv-w8pg-f25f):
5
+ // Security model:
6
6
  // 1. Bind 127.0.0.1 only (never 0.0.0.0)
7
- // 2. Origin validation: Page2AI's Chrome Web Store origin, and the exact origins
8
- // in PAGE2AI_BRIDGE_ORIGINS (a Firefox install, an unpacked build)
7
+ // 2. Origin, a first filter: Page2AI's Chrome Web Store origin, the exact origins
8
+ // in PAGE2AI_BRIDGE_ORIGINS (an unpacked build), and any moz-extension:// origin
9
+ // (Firefox gives every install a random UUID; the key below tells them apart)
9
10
  // 3. Host header: must be 127.0.0.1:PORT or localhost:PORT
10
- // 4. Per-session token: generated on auth, required on every message
11
+ // 4. page2ai-bridge/2: both ends prove they know a key from PAGE2AI_BRIDGE_KEY
12
+ // (protocol.ts). Without a key nothing converts. A socket holds the single
13
+ // slot only after the proof; at most 4 sockets wait in a handshake, 5 s each.
11
14
  import { createServer } from 'node:http';
12
15
  import { randomBytes } from 'node:crypto';
13
16
  import { WebSocketServer, WebSocket } from 'ws';
14
17
  import { BRIDGE_PROTOCOL, BridgeError, DEFAULT_BRIDGE_PORT, } from './protocol.js';
18
+ import { BRIDGE_KEY_ENV, clientProof, isHex64, proofMatches, serverProof } from './keys.js';
15
19
  /** Page2AI's Chrome Web Store ID: Chrome, Edge and the other Chromium browsers
16
20
  * that install from the store send this Origin. */
17
21
  export const PAGE2AI_CHROME_ORIGIN = 'chrome-extension://dlpaaijcnbbmlfeohlphjpnbbcnomnno';
22
+ const MAX_HANDSHAKES = 4;
23
+ const HANDSHAKE_MS = 5000;
24
+ const HOW_TO_ADD_KEY = 'copy the key from the Page2AI popup (Agent Bridge, Copy key) into ' +
25
+ `${BRIDGE_KEY_ENV} in this server's settings, then restart the MCP client`;
26
+ const isWebUrl = (url) => {
27
+ try {
28
+ return /^https?:$/.test(new URL(url).protocol);
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ };
34
+ // The protocol's number, to say which side is older: page2ai-bridge/2 -> 2.
35
+ const protocolNumber = (p) => Number(/^page2ai-bridge\/(\d+)$/.exec(p)?.[1] ?? NaN);
36
+ // What a peer says about itself goes into the log: printable and short only.
37
+ const printable = (v, max = 64) => String(v ?? '').replace(/[^\x20-\x7e]/g, '?').slice(0, max);
18
38
  export class BridgeServer {
19
39
  httpServer = null;
20
40
  wss = null;
21
41
  client = null;
22
- sessionToken = null;
42
+ handshakes = new Set();
23
43
  pending = new Map();
24
44
  requestCounter = 0;
25
45
  port;
26
46
  serverVersion;
27
47
  log;
28
48
  extraOrigins;
49
+ keys;
50
+ handshakeMs;
29
51
  constructor(opts) {
30
52
  this.port = opts.port ?? DEFAULT_BRIDGE_PORT;
31
53
  this.serverVersion = opts.serverVersion;
32
54
  this.log = opts.log;
33
55
  this.extraOrigins = opts.extraOrigins ?? [];
56
+ this.keys = opts.keys ?? [];
57
+ this.handshakeMs = opts.handshakeMs ?? HANDSHAKE_MS;
34
58
  }
59
+ /** An extension that passed the handshake holds the connection. */
35
60
  isConnected() {
36
61
  return this.client !== null && this.client.readyState === WebSocket.OPEN;
37
62
  }
@@ -66,11 +91,16 @@ export class BridgeServer {
66
91
  this.wss = new WebSocketServer({
67
92
  server: this.httpServer,
68
93
  verifyClient: (info, cb) => {
69
- const allowed = this.verifyUpgrade(info.req);
70
- if (!allowed) {
94
+ if (!this.verifyUpgrade(info.req)) {
71
95
  cb(false, 403, 'Forbidden');
72
96
  return;
73
97
  }
98
+ // Sockets that never finish the handshake hold no slot, but they are
99
+ // capped: a flood cannot grow memory, only delay the extension.
100
+ if (this.handshakes.size >= MAX_HANDSHAKES) {
101
+ cb(false, 503, 'Busy');
102
+ return;
103
+ }
74
104
  cb(true);
75
105
  },
76
106
  });
@@ -80,8 +110,11 @@ export class BridgeServer {
80
110
  this.wss.on('error', (err) => {
81
111
  this.log(`bridge wss error: ${err.message}`);
82
112
  });
83
- this.wss.on('connection', (ws, req) => this.handleConnection(ws, req));
84
- this.log(`bridge listening on ws://127.0.0.1:${this.port}`);
113
+ this.wss.on('connection', (ws) => this.handleConnection(ws));
114
+ const keyNote = this.keys.length
115
+ ? `${this.keys.length} key(s): ${this.keys.map((k) => k.id).join(', ')}`
116
+ : `no ${BRIDGE_KEY_ENV}, so no browser can connect yet: ${HOW_TO_ADD_KEY}`;
117
+ this.log(`bridge listening on ws://127.0.0.1:${this.port} (${keyNote})`);
85
118
  }
86
119
  async stop() {
87
120
  for (const [id, req] of this.pending) {
@@ -89,14 +122,20 @@ export class BridgeServer {
89
122
  req.reject(new BridgeError('SHUTTING_DOWN', 'the bridge is shutting down'));
90
123
  this.pending.delete(id);
91
124
  }
92
- this.client?.close();
125
+ // terminate(), not close(): a close handshake waits up to 30 s for a client that
126
+ // never answers (a hung extension, a program holding the slot), and the server
127
+ // waited with it after its client had closed stdin (0.5.3).
128
+ this.client?.terminate();
93
129
  this.client = null;
94
- this.sessionToken = null;
95
130
  if (this.wss) {
131
+ for (const socket of this.wss.clients)
132
+ socket.terminate();
96
133
  this.wss.close();
97
134
  this.wss = null;
98
135
  }
136
+ this.handshakes.clear();
99
137
  if (this.httpServer) {
138
+ this.httpServer.closeAllConnections();
100
139
  await new Promise((resolve) => {
101
140
  this.httpServer.close(() => resolve());
102
141
  });
@@ -128,46 +167,43 @@ export class BridgeServer {
128
167
  });
129
168
  }
130
169
  verifyUpgrade(req) {
131
- // Page2AI only. Any installed extension may open a WebSocket to localhost
132
- // without a permission, and the one holding this single connection reads
133
- // every URL the agent asks for and writes what the agent then reads.
134
- // Firefox gives each install a random moz-extension:// UUID, so a scheme
135
- // check would admit every Firefox extension (0.5.0-0.5.2 did): a Firefox
136
- // install is admitted only by its exact origin in PAGE2AI_BRIDGE_ORIGINS,
137
- // which the Page2AI popup shows there.
170
+ // A first filter, not the lock: the key is. Web pages send http(s) origins and
171
+ // other Chrome extensions their own IDs; Firefox gives each install a random
172
+ // moz-extension:// UUID, so any Firefox origin may try the handshake, and only
173
+ // the key admits Page2AI (0.5.3 required that UUID in PAGE2AI_BRIDGE_ORIGINS).
138
174
  const origin = req.headers.origin ?? '';
139
- if (origin !== PAGE2AI_CHROME_ORIGIN && !this.extraOrigins.includes(origin)) {
140
- const hint = origin.startsWith('moz-extension://')
141
- ? `; if this is Page2AI in Firefox, add PAGE2AI_BRIDGE_ORIGINS=${origin} to this server's environment`
175
+ if (origin !== PAGE2AI_CHROME_ORIGIN && !this.extraOrigins.includes(origin) &&
176
+ !/^moz-extension:\/\/[0-9a-f-]{36}$/i.test(origin)) {
177
+ const hint = origin.startsWith('chrome-extension://')
178
+ ? '; if this is an unpacked Page2AI build, add its origin to PAGE2AI_BRIDGE_ORIGINS'
142
179
  : '';
143
- this.log(`bridge: rejected Origin "${origin}"${hint}`);
180
+ this.log(`bridge: rejected Origin "${printable(origin, 120)}"${hint}`);
144
181
  return false;
145
182
  }
146
183
  const host = req.headers.host ?? '';
147
184
  const allowed = [`127.0.0.1:${this.port}`, `localhost:${this.port}`];
148
185
  if (!allowed.includes(host)) {
149
- this.log(`bridge: rejected Host "${host}"`);
186
+ this.log(`bridge: rejected Host "${printable(host, 120)}"`);
150
187
  return false;
151
188
  }
152
189
  return true;
153
190
  }
154
- handleConnection(ws, _req) {
155
- if (this.client && this.client.readyState === WebSocket.OPEN) {
156
- const err = {
157
- type: 'error',
158
- code: 'ALREADY_CONNECTED',
159
- message: 'Another extension is already connected',
160
- };
191
+ handleConnection(ws) {
192
+ this.handshakes.add(ws);
193
+ let stage = 'hello';
194
+ let key = null;
195
+ let nonceE = '';
196
+ let nonceS = '';
197
+ let peer = '';
198
+ const timer = setTimeout(() => {
199
+ if (stage !== 'open')
200
+ ws.terminate();
201
+ }, this.handshakeMs);
202
+ const refuse = (code, message, extra = {}) => {
203
+ const err = { type: 'error', code, message, ...extra };
161
204
  ws.send(JSON.stringify(err));
162
205
  ws.close();
163
- return;
164
- }
165
- let authenticated = false;
166
- const authTimeout = setTimeout(() => {
167
- if (!authenticated) {
168
- ws.close();
169
- }
170
- }, 5000);
206
+ };
171
207
  ws.on('message', (data) => {
172
208
  let msg;
173
209
  try {
@@ -177,34 +213,71 @@ export class BridgeServer {
177
213
  ws.close();
178
214
  return;
179
215
  }
180
- if (!authenticated) {
181
- if (msg.type === 'hello' && msg.protocol === BRIDGE_PROTOCOL) {
182
- clearTimeout(authTimeout);
183
- authenticated = true;
184
- this.sessionToken = randomBytes(32).toString('hex');
185
- this.client = ws;
186
- const welcome = {
187
- type: 'welcome',
188
- protocol: BRIDGE_PROTOCOL,
189
- serverVersion: this.serverVersion,
190
- token: this.sessionToken,
191
- };
192
- ws.send(JSON.stringify(welcome));
193
- this.log(`bridge: extension connected (${msg.extensionId} v${msg.extensionVersion})`);
216
+ if (!msg || typeof msg !== 'object') {
217
+ ws.close();
218
+ return;
219
+ }
220
+ if (stage === 'hello') {
221
+ if (msg.type !== 'hello') {
222
+ ws.close();
223
+ return;
224
+ }
225
+ peer = `${printable(msg.extensionId)} v${printable(msg.extensionVersion, 20)}`;
226
+ if (msg.protocol !== BRIDGE_PROTOCOL) {
227
+ const theirs = protocolNumber(String(msg.protocol));
228
+ const update = theirs > protocolNumber(BRIDGE_PROTOCOL) ? 'update @page2ai/mcp' : 'update the Page2AI extension';
229
+ this.log(`bridge: refused ${peer}: it speaks ${printable(msg.protocol)}, this server ${BRIDGE_PROTOCOL}; ${update}`);
230
+ refuse('PROTOCOL_MISMATCH', `this server speaks ${BRIDGE_PROTOCOL}`, { protocol: BRIDGE_PROTOCOL });
231
+ return;
232
+ }
233
+ const keyId = /^[0-9a-f]{16}$/.test(String(msg.keyId)) ? String(msg.keyId) : '(none)';
234
+ if (this.keys.length === 0) {
235
+ this.log(`bridge: Page2AI ${peer} (key ${keyId}) asked to connect, but this server has no ${BRIDGE_KEY_ENV}: ${HOW_TO_ADD_KEY}`);
236
+ refuse('NO_KEY', `this server has no ${BRIDGE_KEY_ENV}`);
237
+ return;
194
238
  }
195
- else {
196
- const err = {
197
- type: 'error',
198
- code: 'AUTH_FAILED',
199
- message: `Expected hello with protocol ${BRIDGE_PROTOCOL}`,
200
- };
201
- ws.send(JSON.stringify(err));
239
+ key = this.keys.find((k) => k.id === keyId) ?? null;
240
+ if (!key) {
241
+ this.log(`bridge: refused ${peer}: its key ${keyId} is not in ${BRIDGE_KEY_ENV} ` +
242
+ `(${this.keys.map((k) => k.id).join(', ')}); add it, comma-separated, then restart the MCP client`);
243
+ refuse('UNKNOWN_KEY', `key ${keyId} is not in this server's ${BRIDGE_KEY_ENV}`);
244
+ return;
245
+ }
246
+ if (!isHex64(msg.nonceE)) {
202
247
  ws.close();
248
+ return;
203
249
  }
250
+ nonceE = msg.nonceE;
251
+ nonceS = randomBytes(32).toString('hex');
252
+ stage = 'auth';
253
+ const challenge = {
254
+ type: 'challenge',
255
+ protocol: BRIDGE_PROTOCOL,
256
+ serverVersion: this.serverVersion,
257
+ nonceS,
258
+ proof: serverProof(key.bytes, this.port, nonceE, nonceS),
259
+ };
260
+ ws.send(JSON.stringify(challenge));
204
261
  return;
205
262
  }
206
- if (!('token' in msg) || msg.token !== this.sessionToken) {
207
- ws.close();
263
+ if (stage === 'auth') {
264
+ if (msg.type !== 'auth' || !proofMatches(clientProof(key.bytes, this.port, nonceS, nonceE), msg.proof)) {
265
+ this.log(`bridge: refused ${peer}: it named key ${key.id} but could not prove it`);
266
+ refuse('AUTH_FAILED', 'the proof does not match');
267
+ return;
268
+ }
269
+ clearTimeout(timer);
270
+ this.handshakes.delete(ws);
271
+ if (this.isConnected()) {
272
+ this.log(`bridge: refused ${peer} (key ${key.id}): another browser holds the connection`);
273
+ refuse('ALREADY_CONNECTED', 'another browser is connected to this server');
274
+ return;
275
+ }
276
+ stage = 'open';
277
+ this.client = ws;
278
+ const welcome = { type: 'welcome', protocol: BRIDGE_PROTOCOL, serverVersion: this.serverVersion };
279
+ ws.send(JSON.stringify(welcome));
280
+ this.log(`bridge: extension connected (${peer}, key ${key.id})`);
208
281
  return;
209
282
  }
210
283
  if (msg.type === 'ping') {
@@ -212,27 +285,32 @@ export class BridgeServer {
212
285
  ws.send(JSON.stringify(pong));
213
286
  return;
214
287
  }
215
- if (msg.type === 'result' && 'id' in msg) {
288
+ if (msg.type === 'result' && typeof msg.id === 'string') {
216
289
  const pending = this.pending.get(msg.id);
217
290
  if (pending) {
218
291
  clearTimeout(pending.timer);
219
292
  this.pending.delete(msg.id);
220
- // The agent gets this text as the page: a result without it is an
221
- // extension fault, answered like any other refusal.
222
- if (typeof msg.markdown !== 'string') {
293
+ // The agent gets this text as the page: a result without it, or from a page
294
+ // that is not a web address (Firefox reports an early about:blank complete),
295
+ // is an extension fault, answered like any other refusal. 0.5.3 passed "" on.
296
+ if (typeof msg.markdown !== 'string' || msg.markdown.trim() === '') {
223
297
  pending.reject(new BridgeError('BAD_RESULT', 'the extension sent a result without Markdown'));
224
298
  return;
225
299
  }
300
+ if (typeof msg.url !== 'string' || !isWebUrl(msg.url)) {
301
+ pending.reject(new BridgeError('BAD_RESULT', `the extension sent the text of ${JSON.stringify(msg.url ?? null)}, not of a web page`));
302
+ return;
303
+ }
226
304
  pending.resolve({
227
305
  markdown: msg.markdown,
228
306
  title: typeof msg.title === 'string' ? msg.title : '',
229
- url: typeof msg.url === 'string' ? msg.url : '',
307
+ url: msg.url,
230
308
  charCount: msg.markdown.length,
231
309
  });
232
310
  }
233
311
  return;
234
312
  }
235
- if (msg.type === 'error' && 'id' in msg && msg.id) {
313
+ if (msg.type === 'error' && typeof msg.id === 'string' && msg.id) {
236
314
  const pending = this.pending.get(msg.id);
237
315
  if (pending) {
238
316
  clearTimeout(pending.timer);
@@ -243,10 +321,10 @@ export class BridgeServer {
243
321
  }
244
322
  });
245
323
  ws.on('close', () => {
246
- clearTimeout(authTimeout);
324
+ clearTimeout(timer);
325
+ this.handshakes.delete(ws);
247
326
  if (this.client === ws) {
248
327
  this.client = null;
249
- this.sessionToken = null;
250
328
  this.log('bridge: extension disconnected');
251
329
  // Its requests can no longer be answered: fail them now, not at their timeout.
252
330
  for (const [id, req] of this.pending) {
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/bridge/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/bridge/server.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -18,6 +18,7 @@ import { Server } from '@modelcontextprotocol/server';
18
18
  import { handlePageToMarkdown, pageToMarkdownDefinition, setBridge } from './tools/page-to-markdown.js';
19
19
  import { BridgeServer } from './bridge/server.js';
20
20
  import { DEFAULT_BRIDGE_PORT } from './bridge/protocol.js';
21
+ import { BRIDGE_KEY_ENV, parseBridgeKeys } from './bridge/keys.js';
21
22
  const SERVER_NAME = 'page2ai-mcp';
22
23
  // Read the version from package.json instead of restating it here.
23
24
  //
@@ -83,17 +84,21 @@ const handle = serveStdio(buildServer, {
83
84
  });
84
85
  // --- Agent Bridge: localhost WS for the Page2AI browser extension ---
85
86
  // Starts only in local mode (not on Vercel/serverless). The extension connects
86
- // when the user enables "Agent Bridge" in its popup. When connected, the
87
- // page_to_markdown tool routes through the user's real browser.
87
+ // when the user enables "Agent Bridge" in its popup and this server holds the key
88
+ // the popup shows. When connected, page_to_markdown routes through the user's browser.
88
89
  const isServerless = !!(process.env.VERCEL || process.env.AWS_LAMBDA_FUNCTION_NAME);
89
90
  let bridge = null;
90
91
  if (!isServerless) {
91
92
  const bridgePort = parseInt(process.env.PAGE2AI_BRIDGE_PORT ?? '', 10) || DEFAULT_BRIDGE_PORT;
92
- // An unpacked or self-built extension has its own ID: list its exact origin(s),
93
- // comma-separated, e.g. PAGE2AI_BRIDGE_ORIGINS=chrome-extension://<id>.
93
+ // An unpacked or self-built Chrome extension has its own ID: list its exact
94
+ // origin(s), comma-separated, e.g. PAGE2AI_BRIDGE_ORIGINS=chrome-extension://<id>.
94
95
  const extraOrigins = (process.env.PAGE2AI_BRIDGE_ORIGINS ?? '')
95
96
  .split(',').map((s) => s.trim()).filter(Boolean);
96
- bridge = new BridgeServer({ port: bridgePort, serverVersion: SERVER_VERSION, log, extraOrigins });
97
+ // The key(s) the extension shows in its popup; without one the bridge refuses every browser.
98
+ const { keys, problems } = parseBridgeKeys(process.env[BRIDGE_KEY_ENV]);
99
+ for (const problem of problems)
100
+ log(`${BRIDGE_KEY_ENV}: ${problem}; ignored`);
101
+ bridge = new BridgeServer({ port: bridgePort, serverVersion: SERVER_VERSION, log, extraOrigins, keys });
97
102
  setBridge(bridge);
98
103
  bridge.start().then(() => log(`bridge ready on ws://127.0.0.1:${bridgePort}`), (err) => {
99
104
  log(`bridge failed to start: ${err instanceof Error ? err.message : String(err)} (the server continues without it)`);
@@ -108,6 +113,9 @@ const shutdown = (signal) => {
108
113
  return;
109
114
  shuttingDown = true;
110
115
  log(`${signal} received, closing`);
116
+ // Whatever still holds the event loop after this (a close that never completes),
117
+ // the process ends: its client has gone.
118
+ setTimeout(() => process.exit(0), 3000).unref();
111
119
  const bridgeStop = bridge ? bridge.stop() : Promise.resolve();
112
120
  Promise.all([handle.close(), bridgeStop]).then(() => process.exit(0), (err) => {
113
121
  log(`close failed: ${err instanceof Error ? err.message : String(err)}`);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,yCAAyC;AACzC,+EAA+E;AAC/E,4EAA4E;AAC5E,2EAA2E;AAC3E,EAAE;AACF,8EAA8E;AAC9E,6EAA6E;AAC7E,gFAAgF;AAChF,+EAA+E;AAC/E,8EAA8E;AAC9E,2EAA2E;AAC3E,qEAAqE;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxG,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,MAAM,WAAW,GAAG,aAAa,CAAC;AAElC,mEAAmE;AACnE,EAAE;AACF,mFAAmF;AACnF,8FAA8F;AAC9F,2FAA2F;AAC3F,4FAA4F;AAC5F,EAAE;AACF,2FAA2F;AAC3F,0FAA0F;AAC1F,oDAAoD;AACpD,MAAM,cAAc,GAAG,CAAC,GAAW,EAAE;IACnC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3E,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,eAAe,CAAC;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,eAAe,CAAC;IACzB,CAAC;AACH,CAAC,CAAC,EAAE,CAAC;AAEL,+EAA+E;AAC/E,2EAA2E;AAC3E,MAAM,GAAG,GAAG,CAAC,GAAW,EAAQ,EAAE;IAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,WAAW,KAAK,GAAG,IAAI,CAAC,CAAC;AACpD,CAAC,CAAC;AAEF,iFAAiF;AACjF,0EAA0E;AAC1E,MAAM,WAAW,GAAG,GAAW,EAAE;IAC/B,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,cAAc;QACvB,KAAK,EAAE,SAAS;QAChB,WAAW,EACT,4EAA4E;YAC5E,qFAAqF;YACrF,+BAA+B;QACjC,UAAU,EAAE,4CAA4C;KACzD,EACD;QACE,YAAY,EAAE;YACZ,KAAK,EAAE,EAAE;SACV;KACF,CACF,CAAC;IAEF,MAAM,CAAC,iBAAiB,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAClD,KAAK,EAAE,CAAC,wBAAwB,CAAC;KAClC,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,iBAAiB,CAAC,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACvD,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;QACrC,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;QAChD,IAAI,QAAQ,KAAK,kBAAkB,EAAE,CAAC;YACpC,OAAO,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QACxC,CAAC;QACD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,iBAAiB,QAAQ,EAAE,EAAE,CAAC;SACxE,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,EAAE;IACrC,2EAA2E;IAC3E,6EAA6E;IAC7E,MAAM,EAAE,OAAO;IACf,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,oBAAoB,GAAG,CAAC,OAAO,EAAE,CAAC;CACzD,CAAC,CAAC;AAEH,uEAAuE;AACvE,+EAA+E;AAC/E,yEAAyE;AACzE,gEAAgE;AAChE,MAAM,YAAY,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;AACpF,IAAI,MAAM,GAAwB,IAAI,CAAC;AAEvC,IAAI,CAAC,YAAY,EAAE,CAAC;IAClB,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,mBAAmB,CAAC;IAC9F,gFAAgF;IAChF,wEAAwE;IACxE,MAAM,YAAY,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,EAAE,CAAC;SAC5D,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACnD,MAAM,GAAG,IAAI,YAAY,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC,CAAC;IAClG,SAAS,CAAC,MAAM,CAAC,CAAC;IAElB,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CACjB,GAAG,EAAE,CAAC,GAAG,CAAC,kCAAkC,UAAU,EAAE,CAAC,EACzD,CAAC,GAAY,EAAE,EAAE;QACf,GAAG,CAAC,2BAA2B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;QACrH,MAAM,GAAG,IAAI,CAAC;QACd,SAAS,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC,CACF,CAAC;AACJ,CAAC;AAED,GAAG,CAAC,UAAU,cAAc,2CAA2C,CAAC,CAAC;AAEzE,IAAI,YAAY,GAAG,KAAK,CAAC;AACzB,MAAM,QAAQ,GAAG,CAAC,MAAc,EAAQ,EAAE;IACxC,IAAI,YAAY;QAAE,OAAO;IACzB,YAAY,GAAG,IAAI,CAAC;IACpB,GAAG,CAAC,GAAG,MAAM,oBAAoB,CAAC,CAAC;IACnC,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,CAC5C,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EACrB,CAAC,GAAY,EAAE,EAAE;QACf,GAAG,CAAC,iBAAiB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CACF,CAAC;AACJ,CAAC,CAAC;AAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC/C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;AACjD,uFAAuF;AACvF,sFAAsF;AACtF,qFAAqF;AACrF,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC;AAC1D,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"page-to-markdown.d.ts","sourceRoot":"","sources":["../../src/tools/page-to-markdown.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAWxD,eAAO,MAAM,yBAAyB;;;;;;iBAcpC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAG5E,MAAM,MAAM,oBAAoB,GAAG,cAAc,CAAC;AAElD,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6DpC,CAAC;AAOF,eAAO,MAAM,+BAA+B;;;;;iBAa1C,CAAC;AAEH,eAAO,MAAM,8BAA8B;;;;;;;;;;CAiB1C,CAAC;AAWF,eAAO,MAAM,SAAS,GAAI,QAAQ,YAAY,GAAG,IAAI,KAAG,IAEvD,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,UAAU,OAAO,KAChB,OAAO,CAAC,oBAAoB,CAsG9B,CAAC;AAoBF,eAAO,MAAM,gBAAgB,GAAI,UAAU,MAAM,KAAG,MAKnD,CAAC"}
1
+ {"version":3,"file":"page-to-markdown.d.ts","sourceRoot":"","sources":["../../src/tools/page-to-markdown.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAWxD,eAAO,MAAM,yBAAyB;;;;;;iBAcpC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAG5E,MAAM,MAAM,oBAAoB,GAAG,cAAc,CAAC;AAElD,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6DpC,CAAC;AAOF,eAAO,MAAM,+BAA+B;;;;;iBAa1C,CAAC;AAEH,eAAO,MAAM,8BAA8B;;;;;;;;;;CAiB1C,CAAC;AAWF,eAAO,MAAM,SAAS,GAAI,QAAQ,YAAY,GAAG,IAAI,KAAG,IAEvD,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,UAAU,OAAO,KAChB,OAAO,CAAC,oBAAoB,CAkH9B,CAAC;AAiDF,eAAO,MAAM,gBAAgB,GAAI,UAAU,MAAM,KAAG,MAKnD,CAAC"}
@@ -3,7 +3,8 @@
3
3
  // 15s AbortController timeout, the page-only fetch (no `.md` twin, a browser's
4
4
  // Accept header; core 0.2.0, BL-49), and static tab discovery (emits
5
5
  // `### Tab: {label}` sections for docs sites).
6
- import { fetchAndConvert, htmlToMarkdown, SsrfBlockedError, FetchProtectionError } from '@page2ai/core';
6
+ import { lookup } from 'node:dns/promises';
7
+ import { fetchAndConvert, htmlToMarkdown, assertSafeUrl, findIpBlockReason, SsrfBlockedError, FetchProtectionError, } from '@page2ai/core';
7
8
  import { z } from 'zod';
8
9
  import { BridgeError } from '../bridge/protocol.js';
9
10
  const URL_TEXT = 'Absolute HTTP or HTTPS URL of the web page to convert. Blocks private ranges, loopback, and cloud metadata endpoints. ' +
@@ -149,8 +150,13 @@ export const handlePageToMarkdown = async (rawInput) => {
149
150
  includeImages: input.include_images,
150
151
  includeFrontmatter: input.include_frontmatter,
151
152
  });
153
+ // Only a frontmatter block can carry the line: without one, a page that opens
154
+ // with <hr> starts with `---` too, and 0.5.3 put the line into its text.
152
155
  return {
153
- content: [{ type: 'text', text: markSuppliedHtml(result.markdown) }],
156
+ content: [{
157
+ type: 'text',
158
+ text: input.include_frontmatter ? markSuppliedHtml(result.markdown) : result.markdown,
159
+ }],
154
160
  };
155
161
  }
156
162
  catch (e) {
@@ -168,6 +174,9 @@ export const handlePageToMarkdown = async (rawInput) => {
168
174
  // (0.5.2 matched /timed out/, so a tab-load failure worded so was not retried).
169
175
  let bridgeNote = null;
170
176
  if (bridgeRef?.isConnected()) {
177
+ const blocked = await bridgeBlock(url);
178
+ if (blocked)
179
+ return errorResult(`URL blocked by SSRF guard: ${blocked.message}`);
171
180
  try {
172
181
  const result = await bridgeRef.convert({
173
182
  url,
@@ -175,10 +184,15 @@ export const handlePageToMarkdown = async (rawInput) => {
175
184
  includeFrontmatter: input.include_frontmatter,
176
185
  timeoutMs: input.timeout_ms,
177
186
  });
178
- // A redirect to another host (a sign-in page, most often) is still a success
179
- // for the browser; the agent is told which page it got.
180
- const landed = hostOf(result.url);
181
- const redirectNote = landed && landed !== hostOf(url)
187
+ // The browser follows redirects before anyone sees them: a page it ended on at a
188
+ // blocked address is not handed to the agent.
189
+ const landedBlock = await bridgeBlock(result.url);
190
+ if (landedBlock) {
191
+ return errorResult(`URL blocked by SSRF guard: the page redirected to ${result.url}. ${landedBlock.message}`);
192
+ }
193
+ // A redirect (a sign-in page, most often) is still a success for the browser;
194
+ // the agent is told which page it got.
195
+ const redirectNote = pageOf(result.url) !== pageOf(url)
182
196
  ? [{ type: 'text', text: `Opened in the browser, the page redirected to ${result.url}; the Markdown is of that page.` }]
183
197
  : [];
184
198
  return {
@@ -224,14 +238,45 @@ export const handlePageToMarkdown = async (rawInput) => {
224
238
  // A fetch error after a bridge refusal names both, so the agent can tell the
225
239
  // user what to change in the extension.
226
240
  const fetchError = (message, bridgeNote) => errorResult(bridgeNote ? `${message}\n${bridgeNote}` : message);
227
- const hostOf = (url) => {
241
+ // The page a URL names, to tell a redirect from the same page: host, port and path,
242
+ // without an http-to-https upgrade, a trailing slash, the query or the fragment. 0.5.3
243
+ // compared hosts only, so a same-host sign-in page (`/doc` to `/login`) went unnoted.
244
+ const pageOf = (url) => {
228
245
  try {
229
- return new URL(url).hostname.replace(/\.$/, '').toLowerCase();
246
+ const u = new URL(url);
247
+ return `${u.hostname.replace(/\.$/, '').toLowerCase()}:${u.port}${u.pathname.replace(/\/+$/, '')}`;
230
248
  }
231
249
  catch {
232
250
  return '';
233
251
  }
234
252
  };
253
+ // The tool promises to block private, loopback and metadata addresses, and the server's
254
+ // own fetch does; through the bridge the browser must not open them for the agent either
255
+ // (0.5.0-0.5.3 sent them to the extension). A name this server cannot resolve still goes
256
+ // to the browser, which may reach it through a proxy: only an address the guard names is
257
+ // refused. A browser resolving a name differently (DNS rebinding) is not covered.
258
+ const bridgeBlock = async (url) => {
259
+ let host;
260
+ try {
261
+ host = assertSafeUrl(url).hostname;
262
+ }
263
+ catch (e) {
264
+ return e instanceof SsrfBlockedError ? e : new SsrfBlockedError(String(e), url);
265
+ }
266
+ let addresses;
267
+ try {
268
+ addresses = await lookup(host, { all: true, verbatim: true });
269
+ }
270
+ catch {
271
+ return null;
272
+ }
273
+ for (const { address } of addresses) {
274
+ const reason = findIpBlockReason(address);
275
+ if (reason)
276
+ return new SsrfBlockedError(`hostname "${host}" resolves to blocked address ${address} (${reason})`, url);
277
+ }
278
+ return null;
279
+ };
235
280
  // Markdown made from the caller's HTML names `url` as its source without having fetched
236
281
  // it, so the frontmatter says where the content came from: a copy saved beside fetched
237
282
  // pages must not pass for one (any caller can pair any HTML with any URL).
@@ -1 +1 @@
1
- {"version":3,"file":"page-to-markdown.js","sourceRoot":"","sources":["../../src/tools/page-to-markdown.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"page-to-markdown.js","sourceRoot":"","sources":["../../src/tools/page-to-markdown.ts"],"names":[],"mappings":"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"}
package/manifest.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "manifest_version": "0.3",
3
3
  "name": "page2ai-mcp",
4
4
  "display_name": "Page2AI — Web to Markdown",
5
- "version": "0.5.3",
5
+ "version": "0.6.0",
6
6
  "description": "Convert any web page to clean Markdown for LLM context",
7
7
  "long_description": "Page2AI MCP converts a web page URL to Markdown for AI context windows. It keeps the page's main content (its <main> or dominant <article>), preserves code blocks with language hints, converts tables and lists, and drops navigation, headers, footers and sidebars. The only network requests go to the URL you pass it and the addresses it redirects to, asked for as a browser opens a page, so docs platforms return the page itself rather than a Markdown copy of it: pure Node + linkedom, no external services, no telemetry.\n\nAgent Bridge: when the Page2AI browser extension is connected, the tool routes through the user's real browser — cookies, JavaScript rendering, extension-quality extraction — so pages behind a sign-in and JS-rendered content are within reach. Without the bridge, a page behind a sign-in or rendered only by JavaScript is out of the tool's reach; pass its HTML directly via the `html` parameter.\n\nCompanion to the Page2AI browser extension (https://github.com/igorsaevets/page2ai-extension), which converts the live page in your own browser, including pages behind a sign-in. Built on the open-source @page2ai/core library.",
8
8
  "author": {
@@ -38,7 +38,10 @@
38
38
  "command": "node",
39
39
  "args": [
40
40
  "${__dirname}/dist/index.js"
41
- ]
41
+ ],
42
+ "env": {
43
+ "PAGE2AI_BRIDGE_KEY": "${user_config.bridge_key}"
44
+ }
42
45
  }
43
46
  },
44
47
  "tools": [
@@ -57,5 +60,14 @@
57
60
  "runtimes": {
58
61
  "node": ">=20.0.0"
59
62
  }
63
+ },
64
+ "user_config": {
65
+ "bridge_key": {
66
+ "type": "string",
67
+ "title": "Agent Bridge key",
68
+ "description": "Optional. To let agents open pages in your own browser: in the Page2AI browser extension turn on Agent Bridge, press Copy key, and paste it here. Several browsers: separate their keys with commas.",
69
+ "sensitive": true,
70
+ "required": false
71
+ }
60
72
  }
61
73
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@page2ai/mcp",
3
- "version": "0.5.3",
3
+ "version": "0.6.0",
4
4
  "mcpName": "io.github.igorsaevets/page2ai-mcp",
5
5
  "description": "MCP server that converts any web page URL to clean Markdown for LLM context. Processing is local and SSRF-guarded; no external APIs, no telemetry.",
6
6
  "type": "module",
package/server.json CHANGED
@@ -8,12 +8,12 @@
8
8
  "source": "github"
9
9
  },
10
10
  "websiteUrl": "https://github.com/igorsaevets/page2ai-mcp#readme",
11
- "version": "0.5.3",
11
+ "version": "0.6.0",
12
12
  "packages": [
13
13
  {
14
14
  "registryType": "npm",
15
15
  "identifier": "@page2ai/mcp",
16
- "version": "0.5.3",
16
+ "version": "0.6.0",
17
17
  "transport": {
18
18
  "type": "stdio"
19
19
  }