@page2ai/mcp 0.5.2 → 0.5.4
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 +40 -0
- package/PRIVACY.md +6 -2
- package/README.md +13 -6
- package/dist/bridge/protocol.d.ts +7 -1
- package/dist/bridge/protocol.d.ts.map +1 -1
- package/dist/bridge/protocol.js +10 -0
- package/dist/bridge/protocol.js.map +1 -1
- package/dist/bridge/server.d.ts.map +1 -1
- package/dist/bridge/server.js +46 -17
- package/dist/bridge/server.js.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/tools/page-to-markdown.d.ts +1 -0
- package/dist/tools/page-to-markdown.d.ts.map +1 -1
- package/dist/tools/page-to-markdown.js +90 -8
- package/dist/tools/page-to-markdown.js.map +1 -1
- package/manifest.json +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,46 @@ 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.5.4 - 2026-10-23
|
|
9
|
+
|
|
10
|
+
### Security
|
|
11
|
+
|
|
12
|
+
- **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.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- **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.
|
|
17
|
+
- **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.
|
|
18
|
+
- **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`.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- **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.
|
|
23
|
+
|
|
24
|
+
## 0.5.3 - 2026-10-23
|
|
25
|
+
|
|
26
|
+
### Security
|
|
27
|
+
|
|
28
|
+
- **Agent Bridge no longer accepts every Firefox extension.** 0.5.0 to 0.5.2 accepted any `moz-extension://` origin, because Firefox gives each install a random one; any Firefox extension could then hold the bridge, read the URLs the agent asks for and write what the agent reads. A Firefox install is now accepted only by its exact origin listed in `PAGE2AI_BRIDGE_ORIGINS`, and the server's log names the variable when it refuses one.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- **The server exits when its client closes stdin.** Since 0.5.0 the bridge's listening socket kept the process running after that (0.5.2 was still running 6 s later), holding port 3025, so the client's next instance started without the bridge. CI now checks it (`scripts/stdin-exit.mjs`).
|
|
33
|
+
- **An empty `html` is an error.** With a `url`, `html: ""` fetched the URL instead and a blank `html` converted to an empty page; both now answer `Invalid input: html: empty`.
|
|
34
|
+
- **`url` must be http(s).** zod's `url()` accepted `javascript:`, `file:` and `data:` addresses; the fetch refused them, but as the base of `html` they resolved links and filled `source`.
|
|
35
|
+
- **Bridge failures are classified by their protocol code**, not by words in the message: only `TIMEOUT` ends the call without the server's own fetch. 0.5.2 matched "timed out", so a tab that failed to load was not retried by fetch.
|
|
36
|
+
- **A bridge result without Markdown** is refused (`BAD_RESULT`) and answered by the server's fetch instead of returning an empty text.
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
|
|
40
|
+
- **Markdown made from caller-supplied HTML says so**: its frontmatter adds `provenance: "HTML supplied by the caller; the source URL was not fetched"`, so it does not pass for a fetch of `source`.
|
|
41
|
+
- **Through Agent Bridge, a redirect to another host is reported** in a second text block naming the page the browser ended on (a sign-in page, most often).
|
|
42
|
+
- PRIVACY.md describes Agent Bridge (pages open in the user's own browser; content stays on the machine and goes to the MCP client); SECURITY.md supports 0.5.x and states what the bridge's origin check does and does not stop.
|
|
43
|
+
|
|
44
|
+
### Hosted endpoint (remote 0.1.3)
|
|
45
|
+
|
|
46
|
+
- `html` with a `url` is refused instead of being dropped (the reviewed contract has no `html`, and parsing stripped it, so the caller got a fetch of `url`). The production smoke now also pins the whole `inputSchema` JSON, `title` and `annotations` as served on 2026-10-23.
|
|
47
|
+
|
|
8
48
|
## 0.5.2 - 2026-10-23
|
|
9
49
|
|
|
10
50
|
### Changed
|
package/PRIVACY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Page2AI MCP Server — Privacy Policy
|
|
2
2
|
|
|
3
|
-
**Last updated:** 2026-10-
|
|
3
|
+
**Last updated:** 2026-10-23
|
|
4
4
|
**Applies to:** `@page2ai/mcp` npm package v0.1.0+
|
|
5
5
|
|
|
6
6
|
## What data this MCP server collects
|
|
@@ -31,7 +31,11 @@ The MCP client (Claude Desktop, Cursor, etc.) that invokes `@page2ai/mcp` may lo
|
|
|
31
31
|
|
|
32
32
|
## Authentication
|
|
33
33
|
|
|
34
|
-
`@page2ai/mcp` has no authentication mechanism because it has no user accounts or state.
|
|
34
|
+
`@page2ai/mcp` has no authentication mechanism because it has no user accounts or state. By itself it cannot access content behind login walls or authenticated sessions: it fetches without cookies.
|
|
35
|
+
|
|
36
|
+
## Agent Bridge (since 0.5.0)
|
|
37
|
+
|
|
38
|
+
The server also listens on `ws://127.0.0.1:3025`, on this computer only, for the Page2AI browser extension. When you turn on Agent Bridge in the extension, a page the agent asks for opens in a background tab of your own browser, with your cookies, so its Markdown can include content you are signed in to; that Markdown goes from the extension to this server over the local connection and from here to your MCP client, like any other result. Nothing goes to Page2AI's author or to any server of theirs. Turning the switch off ends it and removes the extension's site access.
|
|
35
39
|
|
|
36
40
|
## Source code and audit
|
|
37
41
|
|
package/README.md
CHANGED
|
@@ -168,17 +168,24 @@ The server fetches without cookies and runs no page scripts. For a page that nee
|
|
|
168
168
|
|
|
169
169
|
- **Pass the HTML you already have** (from Playwright, Chrome DevTools MCP or another browser
|
|
170
170
|
tool) as `html`, with the page's `url`: the HTML is converted, the URL is never fetched, and
|
|
171
|
-
relative links resolve against it.
|
|
171
|
+
relative links resolve against it. The frontmatter then carries `provenance: "HTML supplied by
|
|
172
|
+
the caller; the source URL was not fetched"`. An empty `html` is an error, not a fetch of `url`.
|
|
172
173
|
- **Or turn on Agent Bridge** in the Page2AI extension (1.6.0 or later): popup → *Agent Bridge*
|
|
173
174
|
switch → allow access to websites. While the extension is connected, `url` pages open in a
|
|
174
175
|
background tab of your own browser, with its cookies and scripts, and come back as the
|
|
175
176
|
extension's Markdown (its own output settings apply, not `include_images` /
|
|
176
177
|
`include_frontmatter`). The extension refuses sign-in providers' pages and anything that is
|
|
177
178
|
not http(s); a page it refuses is fetched by the server as usual, with a second text block
|
|
178
|
-
saying why
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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. In Chrome it accepts
|
|
183
|
+
the Page2AI extension alone (its Web Store ID). Firefox gives each install a random origin, so
|
|
184
|
+
a Firefox install is accepted only by its exact origin listed in `PAGE2AI_BRIDGE_ORIGINS`
|
|
185
|
+
(Firefox shows it at `about:debugging#/runtime/this-firefox` as the extension's Internal UUID:
|
|
186
|
+
`moz-extension://<that UUID>`); 0.5.0 to 0.5.2 accepted any Firefox extension. The origin check
|
|
187
|
+
stops web pages and other browser extensions; another program on the same computer can claim
|
|
188
|
+
any origin, so the bridge is no stronger than your user account.
|
|
182
189
|
|
|
183
190
|
## Example prompts
|
|
184
191
|
|
|
@@ -251,7 +258,7 @@ Environment variables of the local server, both optional:
|
|
|
251
258
|
| Variable | Default | Effect |
|
|
252
259
|
|---|---|---|
|
|
253
260
|
| `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 |
|
|
254
|
-
| `PAGE2AI_BRIDGE_ORIGINS` | — |
|
|
261
|
+
| `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>` |
|
|
255
262
|
|
|
256
263
|
Planned: a `profile` argument (`auto | docs | marketing | research | dashboard | wordpress-marketing`).
|
|
257
264
|
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
export declare const BRIDGE_PROTOCOL = "page2ai-bridge/1";
|
|
2
2
|
export declare const DEFAULT_BRIDGE_PORT = 3025;
|
|
3
|
+
/** A bridge failure with the protocol's code (TIMEOUT, PERMISSION_REQUIRED, ...).
|
|
4
|
+
* Callers decide by `code`; the message is for people and may change. */
|
|
5
|
+
export declare class BridgeError extends Error {
|
|
6
|
+
readonly code: string;
|
|
7
|
+
constructor(code: string, message: string);
|
|
8
|
+
}
|
|
3
9
|
export interface HelloMessage {
|
|
4
10
|
type: 'hello';
|
|
5
11
|
protocol: typeof BRIDGE_PROTOCOL;
|
|
@@ -24,7 +30,7 @@ export interface ConvertErrorMessage {
|
|
|
24
30
|
type: 'error';
|
|
25
31
|
id: string;
|
|
26
32
|
token: string;
|
|
27
|
-
code: 'TAB_LOAD_FAILED' | 'EXTRACTION_FAILED' | 'TIMEOUT' | 'RESTRICTED_URL';
|
|
33
|
+
code: 'TAB_LOAD_FAILED' | 'EXTRACTION_FAILED' | 'TIMEOUT' | 'RESTRICTED_URL' | 'PERMISSION_REQUIRED';
|
|
28
34
|
message: string;
|
|
29
35
|
}
|
|
30
36
|
export type ExtensionMessage = HelloMessage | PingMessage | ConvertResultMessage | ConvertErrorMessage;
|
|
@@ -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;
|
|
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"}
|
package/dist/bridge/protocol.js
CHANGED
|
@@ -3,4 +3,14 @@
|
|
|
3
3
|
// Security model: BrowserTools MCP v2.0 (post GHSA-xvrv-w8pg-f25f).
|
|
4
4
|
export const BRIDGE_PROTOCOL = 'page2ai-bridge/1';
|
|
5
5
|
export const DEFAULT_BRIDGE_PORT = 3025;
|
|
6
|
+
/** A bridge failure with the protocol's code (TIMEOUT, PERMISSION_REQUIRED, ...).
|
|
7
|
+
* Callers decide by `code`; the message is for people and may change. */
|
|
8
|
+
export class BridgeError extends Error {
|
|
9
|
+
code;
|
|
10
|
+
constructor(code, message) {
|
|
11
|
+
super(`${code}: ${message}`);
|
|
12
|
+
this.name = 'BridgeError';
|
|
13
|
+
this.code = code;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
6
16
|
//# sourceMappingURL=protocol.js.map
|
|
@@ -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"}
|
|
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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/bridge/server.ts"],"names":[],"mappings":"AAcA,OAAO,
|
|
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;AAgB3F,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;IA2BrB,OAAO,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA4BvE,OAAO,CAAC,aAAa;IA2BrB,OAAO,CAAC,gBAAgB;CA0HzB"}
|
package/dist/bridge/server.js
CHANGED
|
@@ -4,17 +4,25 @@
|
|
|
4
4
|
//
|
|
5
5
|
// Security model (BrowserTools MCP v2.0, post GHSA-xvrv-w8pg-f25f):
|
|
6
6
|
// 1. Bind 127.0.0.1 only (never 0.0.0.0)
|
|
7
|
-
// 2. Origin validation: Page2AI's Chrome Web Store origin,
|
|
8
|
-
// (Firefox
|
|
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)
|
|
9
9
|
// 3. Host header: must be 127.0.0.1:PORT or localhost:PORT
|
|
10
10
|
// 4. Per-session token: generated on auth, required on every message
|
|
11
11
|
import { createServer } from 'node:http';
|
|
12
12
|
import { randomBytes } from 'node:crypto';
|
|
13
13
|
import { WebSocketServer, WebSocket } from 'ws';
|
|
14
|
-
import { BRIDGE_PROTOCOL, DEFAULT_BRIDGE_PORT, } from './protocol.js';
|
|
14
|
+
import { BRIDGE_PROTOCOL, BridgeError, DEFAULT_BRIDGE_PORT, } from './protocol.js';
|
|
15
15
|
/** Page2AI's Chrome Web Store ID: Chrome, Edge and the other Chromium browsers
|
|
16
16
|
* that install from the store send this Origin. */
|
|
17
17
|
export const PAGE2AI_CHROME_ORIGIN = 'chrome-extension://dlpaaijcnbbmlfeohlphjpnbbcnomnno';
|
|
18
|
+
const isWebUrl = (url) => {
|
|
19
|
+
try {
|
|
20
|
+
return /^https?:$/.test(new URL(url).protocol);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
18
26
|
export class BridgeServer {
|
|
19
27
|
httpServer = null;
|
|
20
28
|
wss = null;
|
|
@@ -86,17 +94,23 @@ export class BridgeServer {
|
|
|
86
94
|
async stop() {
|
|
87
95
|
for (const [id, req] of this.pending) {
|
|
88
96
|
clearTimeout(req.timer);
|
|
89
|
-
req.reject(new
|
|
97
|
+
req.reject(new BridgeError('SHUTTING_DOWN', 'the bridge is shutting down'));
|
|
90
98
|
this.pending.delete(id);
|
|
91
99
|
}
|
|
92
|
-
|
|
100
|
+
// terminate(), not close(): a close handshake waits up to 30 s for a client that
|
|
101
|
+
// never answers (a hung extension, a program holding the slot), and the server
|
|
102
|
+
// waited with it after its client had closed stdin (0.5.3).
|
|
103
|
+
this.client?.terminate();
|
|
93
104
|
this.client = null;
|
|
94
105
|
this.sessionToken = null;
|
|
95
106
|
if (this.wss) {
|
|
107
|
+
for (const socket of this.wss.clients)
|
|
108
|
+
socket.terminate();
|
|
96
109
|
this.wss.close();
|
|
97
110
|
this.wss = null;
|
|
98
111
|
}
|
|
99
112
|
if (this.httpServer) {
|
|
113
|
+
this.httpServer.closeAllConnections();
|
|
100
114
|
await new Promise((resolve) => {
|
|
101
115
|
this.httpServer.close(() => resolve());
|
|
102
116
|
});
|
|
@@ -105,7 +119,7 @@ export class BridgeServer {
|
|
|
105
119
|
}
|
|
106
120
|
async convert(opts) {
|
|
107
121
|
if (!this.isConnected()) {
|
|
108
|
-
throw new
|
|
122
|
+
throw new BridgeError('NOT_CONNECTED', 'the extension is not connected');
|
|
109
123
|
}
|
|
110
124
|
const id = `req_${Date.now()}_${++this.requestCounter}`;
|
|
111
125
|
const msg = {
|
|
@@ -121,7 +135,7 @@ export class BridgeServer {
|
|
|
121
135
|
return new Promise((resolve, reject) => {
|
|
122
136
|
const timer = setTimeout(() => {
|
|
123
137
|
this.pending.delete(id);
|
|
124
|
-
reject(new
|
|
138
|
+
reject(new BridgeError('TIMEOUT', `Bridge request timed out after ${opts.timeoutMs}ms`));
|
|
125
139
|
}, opts.timeoutMs + 5000);
|
|
126
140
|
this.pending.set(id, { resolve, reject, timer });
|
|
127
141
|
this.client.send(JSON.stringify(msg));
|
|
@@ -131,12 +145,16 @@ export class BridgeServer {
|
|
|
131
145
|
// Page2AI only. Any installed extension may open a WebSocket to localhost
|
|
132
146
|
// without a permission, and the one holding this single connection reads
|
|
133
147
|
// every URL the agent asks for and writes what the agent then reads.
|
|
134
|
-
// Firefox
|
|
135
|
-
//
|
|
148
|
+
// Firefox gives each install a random moz-extension:// UUID, so a scheme
|
|
149
|
+
// check would admit every Firefox extension (0.5.0-0.5.2 did): a Firefox
|
|
150
|
+
// install is admitted only by its exact origin in PAGE2AI_BRIDGE_ORIGINS (its
|
|
151
|
+
// Internal UUID in about:debugging; the log line below names a refused one).
|
|
136
152
|
const origin = req.headers.origin ?? '';
|
|
137
|
-
if (origin !== PAGE2AI_CHROME_ORIGIN && !
|
|
138
|
-
|
|
139
|
-
|
|
153
|
+
if (origin !== PAGE2AI_CHROME_ORIGIN && !this.extraOrigins.includes(origin)) {
|
|
154
|
+
const hint = origin.startsWith('moz-extension://')
|
|
155
|
+
? `; if this is Page2AI in Firefox, add PAGE2AI_BRIDGE_ORIGINS=${origin} to this server's environment`
|
|
156
|
+
: '';
|
|
157
|
+
this.log(`bridge: rejected Origin "${origin}"${hint}`);
|
|
140
158
|
return false;
|
|
141
159
|
}
|
|
142
160
|
const host = req.headers.host ?? '';
|
|
@@ -213,11 +231,22 @@ export class BridgeServer {
|
|
|
213
231
|
if (pending) {
|
|
214
232
|
clearTimeout(pending.timer);
|
|
215
233
|
this.pending.delete(msg.id);
|
|
234
|
+
// The agent gets this text as the page: a result without it, or from a page
|
|
235
|
+
// that is not a web address (Firefox reports an early about:blank complete),
|
|
236
|
+
// is an extension fault, answered like any other refusal. 0.5.3 passed "" on.
|
|
237
|
+
if (typeof msg.markdown !== 'string' || msg.markdown.trim() === '') {
|
|
238
|
+
pending.reject(new BridgeError('BAD_RESULT', 'the extension sent a result without Markdown'));
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
if (typeof msg.url !== 'string' || !isWebUrl(msg.url)) {
|
|
242
|
+
pending.reject(new BridgeError('BAD_RESULT', `the extension sent the text of ${JSON.stringify(msg.url ?? null)}, not of a web page`));
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
216
245
|
pending.resolve({
|
|
217
246
|
markdown: msg.markdown,
|
|
218
|
-
title: msg.title,
|
|
219
|
-
url: msg.url,
|
|
220
|
-
charCount: msg.
|
|
247
|
+
title: typeof msg.title === 'string' ? msg.title : '',
|
|
248
|
+
url: typeof msg.url === 'string' ? msg.url : '',
|
|
249
|
+
charCount: msg.markdown.length,
|
|
221
250
|
});
|
|
222
251
|
}
|
|
223
252
|
return;
|
|
@@ -227,7 +256,7 @@ export class BridgeServer {
|
|
|
227
256
|
if (pending) {
|
|
228
257
|
clearTimeout(pending.timer);
|
|
229
258
|
this.pending.delete(msg.id);
|
|
230
|
-
pending.reject(new
|
|
259
|
+
pending.reject(new BridgeError(String(msg.code), String(msg.message)));
|
|
231
260
|
}
|
|
232
261
|
return;
|
|
233
262
|
}
|
|
@@ -241,7 +270,7 @@ export class BridgeServer {
|
|
|
241
270
|
// Its requests can no longer be answered: fail them now, not at their timeout.
|
|
242
271
|
for (const [id, req] of this.pending) {
|
|
243
272
|
clearTimeout(req.timer);
|
|
244
|
-
req.reject(new
|
|
273
|
+
req.reject(new BridgeError('EXTENSION_DISCONNECTED', 'the extension closed the connection'));
|
|
245
274
|
this.pending.delete(id);
|
|
246
275
|
}
|
|
247
276
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/bridge/server.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,0EAA0E;AAC1E,+DAA+D;AAC/D,EAAE;AACF,oEAAoE;AACpE,2CAA2C;AAC3C,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/bridge/server.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,0EAA0E;AAC1E,+DAA+D;AAC/D,EAAE;AACF,oEAAoE;AACpE,2CAA2C;AAC3C,mFAAmF;AACnF,wEAAwE;AACxE,6DAA6D;AAC7D,uEAAuE;AAEvE,OAAO,EAAE,YAAY,EAAmD,MAAM,WAAW,CAAC;AAC1F,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAChD,OAAO,EACL,eAAe,EACf,WAAW,EACX,mBAAmB,GAQpB,MAAM,eAAe,CAAC;AAEvB;oDACoD;AACpD,MAAM,CAAC,MAAM,qBAAqB,GAAG,qDAAqD,CAAC;AAE3F,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAW,EAAE;IACxC,IAAI,CAAC;QACH,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC;AAQF,MAAM,OAAO,YAAY;IACf,UAAU,GAAsB,IAAI,CAAC;IACrC,GAAG,GAA2B,IAAI,CAAC;IACnC,MAAM,GAAqB,IAAI,CAAC;IAChC,YAAY,GAAkB,IAAI,CAAC;IACnC,OAAO,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC5C,cAAc,GAAG,CAAC,CAAC;IACV,IAAI,CAAS;IACb,aAAa,CAAS;IACtB,GAAG,CAAwB;IAC3B,YAAY,CAAoB;IAEjD,YAAY,IAMX;QACC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,mBAAmB,CAAC;QAC7C,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;QACxC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;QACpB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;IAC9C,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,MAAM,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,CAAC;IAC3E,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,UAAU,GAAG,YAAY,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YAC3C,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;YACrD,GAAG,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,kEAAkE;QAClE,mEAAmE;QACnE,kEAAkE;QAClE,oEAAoE;QACpE,wEAAwE;QACxE,gEAAgE;QAChE,IAAI,CAAC;YACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC1C,MAAM,OAAO,GAAG,CAAC,GAAU,EAAQ,EAAE;oBACnC,IAAI,CAAC,UAAW,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;oBACvC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACd,CAAC,CAAC;gBACF,IAAI,CAAC,UAAW,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBACxC,IAAI,CAAC,UAAW,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;oBACnD,IAAI,CAAC,UAAW,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;oBACvC,OAAO,EAAE,CAAC;gBACZ,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACvB,MAAM,GAAG,CAAC;QACZ,CAAC;QAED,IAAI,CAAC,GAAG,GAAG,IAAI,eAAe,CAAC;YAC7B,MAAM,EAAE,IAAI,CAAC,UAAU;YACvB,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE;gBACzB,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC7C,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;oBAC5B,OAAO;gBACT,CAAC;gBACD,EAAE,CAAC,IAAI,CAAC,CAAC;YACX,CAAC;SACF,CAAC,CAAC;QAEH,qEAAqE;QACrE,sEAAsE;QACtE,iDAAiD;QACjD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;YAClC,IAAI,CAAC,GAAG,CAAC,qBAAqB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;QAEvE,IAAI,CAAC,GAAG,CAAC,sCAAsC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,IAAI;QACR,KAAK,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACrC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACxB,GAAG,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,eAAe,EAAE,6BAA6B,CAAC,CAAC,CAAC;YAC5E,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC1B,CAAC;QACD,iFAAiF;QACjF,+EAA+E;QAC/E,4DAA4D;QAC5D,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAEzB,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO;gBAAE,MAAM,CAAC,SAAS,EAAE,CAAC;YAC1D,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;YACjB,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;QAClB,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC;YACtC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBAClC,IAAI,CAAC,UAAW,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAA0B;QACtC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,IAAI,WAAW,CAAC,eAAe,EAAE,gCAAgC,CAAC,CAAC;QAC3E,CAAC;QAED,MAAM,EAAE,GAAG,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC;QACxD,MAAM,GAAG,GAA0B;YACjC,IAAI,EAAE,SAAS;YACf,EAAE;YACF,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,OAAO,EAAE;gBACP,aAAa,EAAE,IAAI,CAAC,aAAa;gBACjC,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;gBAC3C,SAAS,EAAE,IAAI,CAAC,SAAS;aAC1B;SACF,CAAC;QAEF,OAAO,IAAI,OAAO,CAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1D,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACxB,MAAM,CAAC,IAAI,WAAW,CAAC,SAAS,EAAE,kCAAkC,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC;YAC3F,CAAC,EAAE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;YAE1B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YACjD,IAAI,CAAC,MAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,aAAa,CAAC,GAAoB;QACxC,0EAA0E;QAC1E,yEAAyE;QACzE,qEAAqE;QACrE,yEAAyE;QACzE,yEAAyE;QACzE,8EAA8E;QAC9E,6EAA6E;QAC7E,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;QACxC,IAAI,MAAM,KAAK,qBAAqB,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5E,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,kBAAkB,CAAC;gBAChD,CAAC,CAAC,+DAA+D,MAAM,+BAA+B;gBACtG,CAAC,CAAC,EAAE,CAAC;YACP,IAAI,CAAC,GAAG,CAAC,4BAA4B,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC;YACvD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,CAAC,aAAa,IAAI,CAAC,IAAI,EAAE,EAAE,aAAa,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACrE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC,GAAG,CAAC,0BAA0B,IAAI,GAAG,CAAC,CAAC;YAC5C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,gBAAgB,CAAC,EAAa,EAAE,IAAqB;QAC3D,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;YAC7D,MAAM,GAAG,GAAuB;gBAC9B,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,mBAAmB;gBACzB,OAAO,EAAE,wCAAwC;aAClD,CAAC;YACF,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAC7B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QAED,IAAI,aAAa,GAAG,KAAK,CAAC;QAC1B,MAAM,WAAW,GAAG,UAAU,CAAC,GAAG,EAAE;YAClC,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,EAAE,CAAC,KAAK,EAAE,CAAC;YACb,CAAC;QACH,CAAC,EAAE,IAAI,CAAC,CAAC;QAET,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE;YACxB,IAAI,GAAqB,CAAC;YAC1B,IAAI,CAAC;gBACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;YACjC,CAAC;YAAC,MAAM,CAAC;gBACP,EAAE,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO;YACT,CAAC;YAED,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,eAAe,EAAE,CAAC;oBAC7D,YAAY,CAAC,WAAW,CAAC,CAAC;oBAC1B,aAAa,GAAG,IAAI,CAAC;oBACrB,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;oBACpD,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;oBAEjB,MAAM,OAAO,GAAmB;wBAC9B,IAAI,EAAE,SAAS;wBACf,QAAQ,EAAE,eAAe;wBACzB,aAAa,EAAE,IAAI,CAAC,aAAa;wBACjC,KAAK,EAAE,IAAI,CAAC,YAAY;qBACzB,CAAC;oBACF,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;oBACjC,IAAI,CAAC,GAAG,CAAC,gCAAgC,GAAG,CAAC,WAAW,KAAK,GAAG,CAAC,gBAAgB,GAAG,CAAC,CAAC;gBACxF,CAAC;qBAAM,CAAC;oBACN,MAAM,GAAG,GAAuB;wBAC9B,IAAI,EAAE,OAAO;wBACb,IAAI,EAAE,aAAa;wBACnB,OAAO,EAAE,gCAAgC,eAAe,EAAE;qBAC3D,CAAC;oBACF,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;oBAC7B,EAAE,CAAC,KAAK,EAAE,CAAC;gBACb,CAAC;gBACD,OAAO;YACT,CAAC;YAED,IAAI,CAAC,CAAC,OAAO,IAAI,GAAG,CAAC,IAAK,GAA0B,CAAC,KAAK,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;gBACjF,EAAE,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO;YACT,CAAC;YAED,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gBAC3C,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC9B,OAAO;YACT,CAAC;YAED,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC;gBACzC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACzC,IAAI,OAAO,EAAE,CAAC;oBACZ,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBAC5B,4EAA4E;oBAC5E,6EAA6E;oBAC7E,8EAA8E;oBAC9E,IAAI,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;wBACnE,OAAO,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,YAAY,EAAE,8CAA8C,CAAC,CAAC,CAAC;wBAC9F,OAAO;oBACT,CAAC;oBACD,IAAI,OAAO,GAAG,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtD,OAAO,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,YAAY,EAAE,kCAAkC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;wBACtI,OAAO;oBACT,CAAC;oBACD,OAAO,CAAC,OAAO,CAAC;wBACd,QAAQ,EAAE,GAAG,CAAC,QAAQ;wBACtB,KAAK,EAAE,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;wBACrD,GAAG,EAAE,OAAO,GAAG,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;wBAC/C,SAAS,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM;qBAC/B,CAAC,CAAC;gBACL,CAAC;gBACD,OAAO;YACT,CAAC;YAED,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,IAAI,GAAG,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;gBAClD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACzC,IAAI,OAAO,EAAE,CAAC;oBACZ,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBAC5B,OAAO,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBACzE,CAAC;gBACD,OAAO;YACT,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YAClB,YAAY,CAAC,WAAW,CAAC,CAAC;YAC1B,IAAI,IAAI,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;gBACvB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;gBACnB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;gBACzB,IAAI,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;gBAC3C,+EAA+E;gBAC/E,KAAK,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;oBACrC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;oBACxB,GAAG,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,wBAAwB,EAAE,qCAAqC,CAAC,CAAC,CAAC;oBAC7F,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACrB,IAAI,CAAC,GAAG,CAAC,qBAAqB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
|
package/dist/index.js
CHANGED
|
@@ -102,8 +102,15 @@ if (!isServerless) {
|
|
|
102
102
|
});
|
|
103
103
|
}
|
|
104
104
|
log(`server ${SERVER_VERSION} ready on stdio (tools: page_to_markdown)`);
|
|
105
|
+
let shuttingDown = false;
|
|
105
106
|
const shutdown = (signal) => {
|
|
107
|
+
if (shuttingDown)
|
|
108
|
+
return;
|
|
109
|
+
shuttingDown = true;
|
|
106
110
|
log(`${signal} received, closing`);
|
|
111
|
+
// Whatever still holds the event loop after this (a close that never completes),
|
|
112
|
+
// the process ends: its client has gone.
|
|
113
|
+
setTimeout(() => process.exit(0), 3000).unref();
|
|
107
114
|
const bridgeStop = bridge ? bridge.stop() : Promise.resolve();
|
|
108
115
|
Promise.all([handle.close(), bridgeStop]).then(() => process.exit(0), (err) => {
|
|
109
116
|
log(`close failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -112,4 +119,9 @@ const shutdown = (signal) => {
|
|
|
112
119
|
};
|
|
113
120
|
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
114
121
|
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
122
|
+
// A client ends a stdio session by closing stdin (the MCP spec's first shutdown step).
|
|
123
|
+
// The bridge's listening socket would keep this process alive after that, holding the
|
|
124
|
+
// port against the client's next instance: 0.5.0-0.5.2 were still running 6 s later.
|
|
125
|
+
process.stdin.once('end', () => shutdown('stdin closed'));
|
|
126
|
+
process.stdin.once('close', () => shutdown('stdin closed'));
|
|
115
127
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -73,4 +73,5 @@ export declare const pageToMarkdownHostedDefinition: {
|
|
|
73
73
|
};
|
|
74
74
|
export declare const setBridge: (bridge: BridgeServer | null) => void;
|
|
75
75
|
export declare const handlePageToMarkdown: (rawInput: unknown) => Promise<PageToMarkdownResult>;
|
|
76
|
+
export declare const markSuppliedHtml: (markdown: string) => string;
|
|
76
77
|
//# sourceMappingURL=page-to-markdown.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-to-markdown.d.ts","sourceRoot":"","sources":["../../src/tools/page-to-markdown.ts"],"names":[],"mappings":"
|
|
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,8 +3,10 @@
|
|
|
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 {
|
|
6
|
+
import { lookup } from 'node:dns/promises';
|
|
7
|
+
import { fetchAndConvert, htmlToMarkdown, assertSafeUrl, findIpBlockReason, SsrfBlockedError, FetchProtectionError, } from '@page2ai/core';
|
|
7
8
|
import { z } from 'zod';
|
|
9
|
+
import { BridgeError } from '../bridge/protocol.js';
|
|
8
10
|
const URL_TEXT = 'Absolute HTTP or HTTPS URL of the web page to convert. Blocks private ranges, loopback, and cloud metadata endpoints. ' +
|
|
9
11
|
'Given with `html`, it is not fetched: it names the page the HTML came from, and relative links resolve against it.';
|
|
10
12
|
const HTML_TEXT = 'Raw HTML of the page to convert instead of fetching it, e.g. from a browser tool. ' +
|
|
@@ -16,7 +18,7 @@ export const pageToMarkdownInputSchema = z.object({
|
|
|
16
18
|
include_images: z.boolean().optional().default(true).describe('Include image references () in the output. Default: true.' + BRIDGE_SETTINGS_TEXT),
|
|
17
19
|
include_frontmatter: z.boolean().optional().default(true).describe('Prepend a YAML frontmatter block with title, source URL, capture timestamp, language, description, and canonical URL. Default: true.' + BRIDGE_SETTINGS_TEXT),
|
|
18
20
|
timeout_ms: z.number().int().min(1000).max(60000).optional().default(15000).describe('Abort the fetch after N milliseconds. Range: 1000-60000. Default: 15000.'),
|
|
19
|
-
}).refine((data) => data.url || data.html, {
|
|
21
|
+
}).refine((data) => data.url !== undefined || data.html !== undefined, {
|
|
20
22
|
message: 'Provide `url`, `html`, or both.',
|
|
21
23
|
});
|
|
22
24
|
export const pageToMarkdownDefinition = {
|
|
@@ -129,18 +131,32 @@ export const handlePageToMarkdown = async (rawInput) => {
|
|
|
129
131
|
: String(e);
|
|
130
132
|
return errorResult(`Invalid input: ${msg}`);
|
|
131
133
|
}
|
|
134
|
+
// zod's url() takes any scheme (javascript:, file:, data:). The fetch would refuse
|
|
135
|
+
// them, but as the base of `html` one would resolve links and fill `source` unchecked.
|
|
136
|
+
if (input.url !== undefined && !/^https?:$/.test(new URL(input.url).protocol)) {
|
|
137
|
+
return errorResult('Invalid input: url: only http:// and https:// addresses are accepted');
|
|
138
|
+
}
|
|
132
139
|
// --- Path 1: raw HTML provided → convert locally via htmlToMarkdown (mcp#1) ---
|
|
133
140
|
// A `url` given with it is the page's address, never fetched: relative links resolve
|
|
134
|
-
// against it and it fills the frontmatter's `source`.
|
|
135
|
-
|
|
141
|
+
// against it and it fills the frontmatter's `source`. An empty `html` is an error, not
|
|
142
|
+
// a reason to fetch `url` instead: the caller chose the HTML route (0.5.2 fetched on "").
|
|
143
|
+
if (input.html !== undefined) {
|
|
144
|
+
if (input.html.trim() === '') {
|
|
145
|
+
return errorResult('Invalid input: html: empty. Send the page\'s HTML, or leave html out to fetch url.');
|
|
146
|
+
}
|
|
136
147
|
try {
|
|
137
148
|
const result = htmlToMarkdown(input.html, {
|
|
138
149
|
baseUrl: input.url,
|
|
139
150
|
includeImages: input.include_images,
|
|
140
151
|
includeFrontmatter: input.include_frontmatter,
|
|
141
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.
|
|
142
155
|
return {
|
|
143
|
-
content: [{
|
|
156
|
+
content: [{
|
|
157
|
+
type: 'text',
|
|
158
|
+
text: input.include_frontmatter ? markSuppliedHtml(result.markdown) : result.markdown,
|
|
159
|
+
}],
|
|
144
160
|
};
|
|
145
161
|
}
|
|
146
162
|
catch (e) {
|
|
@@ -154,9 +170,13 @@ export const handlePageToMarkdown = async (rawInput) => {
|
|
|
154
170
|
// A refusal (no site access, a sensitive or non-web URL) or a failed tab falls
|
|
155
171
|
// through to the server's own fetch, as if no extension were connected, with a
|
|
156
172
|
// note saying why; a timeout does not, since the fetch would spend the caller's
|
|
157
|
-
// time a second time.
|
|
173
|
+
// time a second time. The protocol's code decides, never the message's wording
|
|
174
|
+
// (0.5.2 matched /timed out/, so a tab-load failure worded so was not retried).
|
|
158
175
|
let bridgeNote = null;
|
|
159
176
|
if (bridgeRef?.isConnected()) {
|
|
177
|
+
const blocked = await bridgeBlock(url);
|
|
178
|
+
if (blocked)
|
|
179
|
+
return errorResult(`URL blocked by SSRF guard: ${blocked.message}`);
|
|
160
180
|
try {
|
|
161
181
|
const result = await bridgeRef.convert({
|
|
162
182
|
url,
|
|
@@ -164,13 +184,24 @@ export const handlePageToMarkdown = async (rawInput) => {
|
|
|
164
184
|
includeFrontmatter: input.include_frontmatter,
|
|
165
185
|
timeoutMs: input.timeout_ms,
|
|
166
186
|
});
|
|
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)
|
|
196
|
+
? [{ type: 'text', text: `Opened in the browser, the page redirected to ${result.url}; the Markdown is of that page.` }]
|
|
197
|
+
: [];
|
|
167
198
|
return {
|
|
168
|
-
content: [{ type: 'text', text: result.markdown }],
|
|
199
|
+
content: [{ type: 'text', text: result.markdown }, ...redirectNote],
|
|
169
200
|
};
|
|
170
201
|
}
|
|
171
202
|
catch (e) {
|
|
172
203
|
const msg = e instanceof Error ? e.message : String(e);
|
|
173
|
-
if (
|
|
204
|
+
if (e instanceof BridgeError && e.code === 'TIMEOUT')
|
|
174
205
|
return errorResult(`Bridge conversion failed: ${msg}`);
|
|
175
206
|
process.stderr.write(`[page2ai-mcp] bridge: ${msg}; fetching without the browser\n`);
|
|
176
207
|
bridgeNote = `Fetched without the browser: the Page2AI extension answered ${msg}`;
|
|
@@ -207,4 +238,55 @@ export const handlePageToMarkdown = async (rawInput) => {
|
|
|
207
238
|
// A fetch error after a bridge refusal names both, so the agent can tell the
|
|
208
239
|
// user what to change in the extension.
|
|
209
240
|
const fetchError = (message, bridgeNote) => errorResult(bridgeNote ? `${message}\n${bridgeNote}` : message);
|
|
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) => {
|
|
245
|
+
try {
|
|
246
|
+
const u = new URL(url);
|
|
247
|
+
return `${u.hostname.replace(/\.$/, '').toLowerCase()}:${u.port}${u.pathname.replace(/\/+$/, '')}`;
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
return '';
|
|
251
|
+
}
|
|
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
|
+
};
|
|
280
|
+
// Markdown made from the caller's HTML names `url` as its source without having fetched
|
|
281
|
+
// it, so the frontmatter says where the content came from: a copy saved beside fetched
|
|
282
|
+
// pages must not pass for one (any caller can pair any HTML with any URL).
|
|
283
|
+
const PROVENANCE_LINE = 'provenance: "HTML supplied by the caller; the source URL was not fetched"';
|
|
284
|
+
export const markSuppliedHtml = (markdown) => {
|
|
285
|
+
if (!markdown.startsWith('---\n'))
|
|
286
|
+
return markdown;
|
|
287
|
+
const end = markdown.indexOf('\n---', 4);
|
|
288
|
+
if (end < 0)
|
|
289
|
+
return markdown;
|
|
290
|
+
return `${markdown.slice(0, end)}\n${PROVENANCE_LINE}${markdown.slice(end)}`;
|
|
291
|
+
};
|
|
210
292
|
//# sourceMappingURL=page-to-markdown.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-to-markdown.js","sourceRoot":"","sources":["../../src/tools/page-to-markdown.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,+EAA+E;AAC/E,+EAA+E;AAC/E,qEAAqE;AACrE,+CAA+C;AAE/C,OAAO,EAAE,
|
|
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.
|
|
5
|
+
"version": "0.5.4",
|
|
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": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@page2ai/mcp",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
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.
|
|
11
|
+
"version": "0.5.4",
|
|
12
12
|
"packages": [
|
|
13
13
|
{
|
|
14
14
|
"registryType": "npm",
|
|
15
15
|
"identifier": "@page2ai/mcp",
|
|
16
|
-
"version": "0.5.
|
|
16
|
+
"version": "0.5.4",
|
|
17
17
|
"transport": {
|
|
18
18
|
"type": "stdio"
|
|
19
19
|
}
|