@page2ai/mcp 0.5.4 → 0.6.1
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 +29 -0
- package/README.md +23 -10
- package/dist/bridge/keys.d.ts +22 -0
- package/dist/bridge/keys.d.ts.map +1 -0
- package/dist/bridge/keys.js +46 -0
- package/dist/bridge/keys.js.map +1 -0
- package/dist/bridge/protocol.d.ts +23 -8
- package/dist/bridge/protocol.d.ts.map +1 -1
- package/dist/bridge/protocol.js +11 -2
- package/dist/bridge/protocol.js.map +1 -1
- package/dist/bridge/server.d.ts +9 -1
- package/dist/bridge/server.d.ts.map +1 -1
- package/dist/bridge/server.js +140 -68
- package/dist/bridge/server.js.map +1 -1
- package/dist/index.js +10 -5
- package/dist/index.js.map +1 -1
- package/manifest.json +14 -2
- package/package.json +1 -1
- package/server.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,35 @@ 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.1 - 2026-10-24
|
|
9
|
+
|
|
10
|
+
Fixes from the review panel of 0.6.0.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **A refused bridge connection is not read any more.** 0.6.0 kept reading a socket it had refused until the socket closed: each further `hello` wrote another refusal line into the MCP client's log, and a client that failed the proof could try again on the same socket (it still needed the key).
|
|
15
|
+
- **`PAGE2AI_BRIDGE_KEY="<key>"` is read.** 0.6.0 removed the quotes before the variable's name, so the value kept a quote and was refused. Also read now: spaces around `=`, a JSON pair `"PAGE2AI_BRIDGE_KEY": "<key>"`, `export PAGE2AI_BRIDGE_KEY=<key>`.
|
|
16
|
+
- **Firefox's stable origin form** (`moz-extension://` and 64 letters a-p, added in Firefox 150 for WebAuthn) may start the handshake too, so a later switch of extension pages to it does not shut Firefox out. The key still decides.
|
|
17
|
+
|
|
18
|
+
### Docs
|
|
19
|
+
|
|
20
|
+
- README: `PAGE2AI_BRIDGE_PORT` is for tests, since the extension connects to 3025 only; with several MCP clients the one started first holds the port, so each needs the key; a new key replaces the old one. SECURITY.md: what a local program can still do (keep the bridge from connecting, not read from it), and that the key does not encrypt.
|
|
21
|
+
|
|
22
|
+
### Tests
|
|
23
|
+
|
|
24
|
+
- `tests/bridge-fallback.test.ts` no longer reaches the machine's DNS, which failed it once in five runs.
|
|
25
|
+
|
|
26
|
+
## 0.6.0 - 2026-10-24
|
|
27
|
+
|
|
28
|
+
### Security
|
|
29
|
+
|
|
30
|
+
- **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).
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
- **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.
|
|
35
|
+
- The per-session token of `page2ai-bridge/1` is gone: the authenticated connection is the session.
|
|
36
|
+
|
|
8
37
|
## 0.5.4 - 2026-10-23
|
|
9
38
|
|
|
10
39
|
### Security
|
package/README.md
CHANGED
|
@@ -179,13 +179,25 @@ The server fetches without cookies and runs no page scripts. For a page that nee
|
|
|
179
179
|
saying why; when the browser ends on another page (a sign-in redirect), a second text block
|
|
180
180
|
names the page it got. Private, loopback and cloud metadata addresses are refused before the
|
|
181
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
|
-
|
|
185
|
-
|
|
186
|
-
`
|
|
187
|
-
|
|
188
|
-
|
|
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. Several MCP clients running Page2AI (Claude
|
|
191
|
+
Desktop and Cursor, say): the one started first holds port 3025 and the others run without the
|
|
192
|
+
bridge, so give the key to each of them. Without a key the server never sends a page to a
|
|
193
|
+
browser, and the popup and this server's log say what to paste where. On every connection both
|
|
194
|
+
sides prove they know the key (an HMAC exchange; the key never crosses the socket), the server
|
|
195
|
+
first: a program that took port 3025 while no server ran gets nothing from the extension, and a
|
|
196
|
+
program that connects to the server without the key cannot ask it for pages. Firefox needs no
|
|
197
|
+
extra setting since 0.6.0 (0.5.3 required the install's UUID in `PAGE2AI_BRIDGE_ORIGINS`).
|
|
198
|
+
*New key* in the popup, or reinstalling the extension, makes a new key: replace the old one with it.
|
|
199
|
+
Whoever reads your MCP client's config or the browser profile can read the key: the bridge is
|
|
200
|
+
no stronger than your user account.
|
|
189
201
|
|
|
190
202
|
## Example prompts
|
|
191
203
|
|
|
@@ -253,12 +265,13 @@ No setup required — every argument has a sensible default. `page_to_markdown`
|
|
|
253
265
|
The hosted endpoint takes `url` only (the contract its ChatGPT plugin was reviewed with) and
|
|
254
266
|
caps `timeout_ms` at 20000.
|
|
255
267
|
|
|
256
|
-
Environment variables of the local server,
|
|
268
|
+
Environment variables of the local server, all optional:
|
|
257
269
|
|
|
258
270
|
| Variable | Default | Effect |
|
|
259
271
|
|---|---|---|
|
|
260
|
-
| `
|
|
261
|
-
| `
|
|
272
|
+
| `PAGE2AI_BRIDGE_KEY` | — | The Agent Bridge key(s) from the Page2AI popup, comma-separated. Without one the bridge connects no browser |
|
|
273
|
+
| `PAGE2AI_BRIDGE_PORT` | `3025` | Port of the Agent Bridge on 127.0.0.1. The extension connects to 3025 only, so change it for tests, not for a browser. If it is taken (another running instance), the server starts without the bridge |
|
|
274
|
+
| `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 |
|
|
262
275
|
|
|
263
276
|
Planned: a `profile` argument (`auto | docs | marketing | research | dashboard | wordpress-marketing`).
|
|
264
277
|
|
|
@@ -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 `=` or `:`); an MCPB field left empty may
|
|
10
|
+
* arrive unexpanded and counts as no key. A bad entry is reported by its position,
|
|
11
|
+
* never 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;AAQD,eAAO,MAAM,OAAO,GAAI,OAAO,MAAM,KAAG,MACuB,CAAC;AAEhE;;;kEAGkE;AAClE,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,46 @@
|
|
|
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
|
+
// The variable's own name pasted along: an env line, a shell export or a JSON pair.
|
|
11
|
+
const NAME_PREFIX = new RegExp(`^(?:export\\s+)?["']?${BRIDGE_KEY_ENV}["']?\\s*[:=]\\s*`);
|
|
12
|
+
const HEX64 = /^[0-9a-f]{64}$/;
|
|
13
|
+
export const keyIdOf = (bytes) => createHash('sha256').update(bytes).digest('hex').slice(0, 16);
|
|
14
|
+
/** Reads PAGE2AI_BRIDGE_KEY. Tolerates what a copy-paste brings along (spaces,
|
|
15
|
+
* quotes, the variable's own name before `=` or `:`); an MCPB field left empty may
|
|
16
|
+
* arrive unexpanded and counts as no key. A bad entry is reported by its position,
|
|
17
|
+
* never by its value: the log goes to the MCP client's files. */
|
|
18
|
+
export const parseBridgeKeys = (raw) => {
|
|
19
|
+
const keys = [];
|
|
20
|
+
const problems = [];
|
|
21
|
+
const entries = (raw ?? '').split(',');
|
|
22
|
+
entries.forEach((entry, i) => {
|
|
23
|
+
// The name first, then the quotes: 0.6.0 did it the other way round and refused NAME="key".
|
|
24
|
+
const s = entry.trim().replace(NAME_PREFIX, '').replace(/^["']+|["']+$/g, '').trim();
|
|
25
|
+
if (s === '' || s.includes('${'))
|
|
26
|
+
return;
|
|
27
|
+
if (!KEY_PATTERN.test(s)) {
|
|
28
|
+
problems.push(`entry ${i + 1} of ${entries.length} is not a Page2AI key ` +
|
|
29
|
+
`(${s.length} characters; a key from the extension's popup has 43)`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const bytes = Buffer.from(s.replace(/=$/, ''), 'base64url');
|
|
33
|
+
const id = keyIdOf(bytes);
|
|
34
|
+
if (!keys.some((k) => k.id === id))
|
|
35
|
+
keys.push({ id, bytes });
|
|
36
|
+
});
|
|
37
|
+
return { keys, problems };
|
|
38
|
+
};
|
|
39
|
+
export const isHex64 = (v) => typeof v === 'string' && HEX64.test(v);
|
|
40
|
+
const proofOf = (key, text) => createHmac('sha256', key).update(text).digest('hex');
|
|
41
|
+
/** What the server sends: it knows the key, on this port, for this hello. */
|
|
42
|
+
export const serverProof = (key, port, nonceE, nonceS) => proofOf(key, `${BRIDGE_PROTOCOL}|server|${port}|${nonceE}|${nonceS}`);
|
|
43
|
+
/** What the extension sends back once the server's proof checked out. */
|
|
44
|
+
export const clientProof = (key, port, nonceS, nonceE) => proofOf(key, `${BRIDGE_PROTOCOL}|client|${port}|${nonceS}|${nonceE}`);
|
|
45
|
+
export const proofMatches = (expected, got) => isHex64(got) && timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(got, 'hex'));
|
|
46
|
+
//# 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
|
+
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:
|
|
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":"
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/bridge/protocol.ts"],"names":[],"mappings":"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"}
|
package/dist/bridge/protocol.js
CHANGED
|
@@ -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
|
-
//
|
|
4
|
-
|
|
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,
|
|
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"}
|
package/dist/bridge/server.d.ts
CHANGED
|
@@ -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
|
|
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":"
|
|
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;IA0BrB,OAAO,CAAC,gBAAgB;CAyKzB"}
|
package/dist/bridge/server.js
CHANGED
|
@@ -2,19 +2,27 @@
|
|
|
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
|
|
5
|
+
// Security model:
|
|
6
6
|
// 1. Bind 127.0.0.1 only (never 0.0.0.0)
|
|
7
|
-
// 2. Origin
|
|
8
|
-
// in PAGE2AI_BRIDGE_ORIGINS (
|
|
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.
|
|
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`;
|
|
18
26
|
const isWebUrl = (url) => {
|
|
19
27
|
try {
|
|
20
28
|
return /^https?:$/.test(new URL(url).protocol);
|
|
@@ -23,23 +31,32 @@ const isWebUrl = (url) => {
|
|
|
23
31
|
return false;
|
|
24
32
|
}
|
|
25
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);
|
|
26
38
|
export class BridgeServer {
|
|
27
39
|
httpServer = null;
|
|
28
40
|
wss = null;
|
|
29
41
|
client = null;
|
|
30
|
-
|
|
42
|
+
handshakes = new Set();
|
|
31
43
|
pending = new Map();
|
|
32
44
|
requestCounter = 0;
|
|
33
45
|
port;
|
|
34
46
|
serverVersion;
|
|
35
47
|
log;
|
|
36
48
|
extraOrigins;
|
|
49
|
+
keys;
|
|
50
|
+
handshakeMs;
|
|
37
51
|
constructor(opts) {
|
|
38
52
|
this.port = opts.port ?? DEFAULT_BRIDGE_PORT;
|
|
39
53
|
this.serverVersion = opts.serverVersion;
|
|
40
54
|
this.log = opts.log;
|
|
41
55
|
this.extraOrigins = opts.extraOrigins ?? [];
|
|
56
|
+
this.keys = opts.keys ?? [];
|
|
57
|
+
this.handshakeMs = opts.handshakeMs ?? HANDSHAKE_MS;
|
|
42
58
|
}
|
|
59
|
+
/** An extension that passed the handshake holds the connection. */
|
|
43
60
|
isConnected() {
|
|
44
61
|
return this.client !== null && this.client.readyState === WebSocket.OPEN;
|
|
45
62
|
}
|
|
@@ -74,11 +91,16 @@ export class BridgeServer {
|
|
|
74
91
|
this.wss = new WebSocketServer({
|
|
75
92
|
server: this.httpServer,
|
|
76
93
|
verifyClient: (info, cb) => {
|
|
77
|
-
|
|
78
|
-
if (!allowed) {
|
|
94
|
+
if (!this.verifyUpgrade(info.req)) {
|
|
79
95
|
cb(false, 403, 'Forbidden');
|
|
80
96
|
return;
|
|
81
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
|
+
}
|
|
82
104
|
cb(true);
|
|
83
105
|
},
|
|
84
106
|
});
|
|
@@ -88,8 +110,11 @@ export class BridgeServer {
|
|
|
88
110
|
this.wss.on('error', (err) => {
|
|
89
111
|
this.log(`bridge wss error: ${err.message}`);
|
|
90
112
|
});
|
|
91
|
-
this.wss.on('connection', (ws
|
|
92
|
-
|
|
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})`);
|
|
93
118
|
}
|
|
94
119
|
async stop() {
|
|
95
120
|
for (const [id, req] of this.pending) {
|
|
@@ -102,13 +127,13 @@ export class BridgeServer {
|
|
|
102
127
|
// waited with it after its client had closed stdin (0.5.3).
|
|
103
128
|
this.client?.terminate();
|
|
104
129
|
this.client = null;
|
|
105
|
-
this.sessionToken = null;
|
|
106
130
|
if (this.wss) {
|
|
107
131
|
for (const socket of this.wss.clients)
|
|
108
132
|
socket.terminate();
|
|
109
133
|
this.wss.close();
|
|
110
134
|
this.wss = null;
|
|
111
135
|
}
|
|
136
|
+
this.handshakes.clear();
|
|
112
137
|
if (this.httpServer) {
|
|
113
138
|
this.httpServer.closeAllConnections();
|
|
114
139
|
await new Promise((resolve) => {
|
|
@@ -142,91 +167,138 @@ export class BridgeServer {
|
|
|
142
167
|
});
|
|
143
168
|
}
|
|
144
169
|
verifyUpgrade(req) {
|
|
145
|
-
//
|
|
146
|
-
//
|
|
147
|
-
//
|
|
148
|
-
//
|
|
149
|
-
//
|
|
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).
|
|
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).
|
|
174
|
+
// Firefox 150 added a stable form, 64 letters a-p, for WebAuthn; it is let in too.
|
|
152
175
|
const origin = req.headers.origin ?? '';
|
|
153
|
-
if (origin !== PAGE2AI_CHROME_ORIGIN && !this.extraOrigins.includes(origin)
|
|
154
|
-
|
|
155
|
-
|
|
176
|
+
if (origin !== PAGE2AI_CHROME_ORIGIN && !this.extraOrigins.includes(origin) &&
|
|
177
|
+
!/^moz-extension:\/\/(?:[0-9a-f-]{36}|[a-p]{64})$/i.test(origin)) {
|
|
178
|
+
const hint = origin.startsWith('chrome-extension://')
|
|
179
|
+
? '; if this is an unpacked Page2AI build, add its origin to PAGE2AI_BRIDGE_ORIGINS'
|
|
156
180
|
: '';
|
|
157
|
-
this.log(`bridge: rejected Origin "${origin}"${hint}`);
|
|
181
|
+
this.log(`bridge: rejected Origin "${printable(origin, 120)}"${hint}`);
|
|
158
182
|
return false;
|
|
159
183
|
}
|
|
160
184
|
const host = req.headers.host ?? '';
|
|
161
185
|
const allowed = [`127.0.0.1:${this.port}`, `localhost:${this.port}`];
|
|
162
186
|
if (!allowed.includes(host)) {
|
|
163
|
-
this.log(`bridge: rejected Host "${host}"`);
|
|
187
|
+
this.log(`bridge: rejected Host "${printable(host, 120)}"`);
|
|
164
188
|
return false;
|
|
165
189
|
}
|
|
166
190
|
return true;
|
|
167
191
|
}
|
|
168
|
-
handleConnection(ws
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
192
|
+
handleConnection(ws) {
|
|
193
|
+
this.handshakes.add(ws);
|
|
194
|
+
// 'closed': refused, and nothing it sends is read any more. 0.6.0 read on until the
|
|
195
|
+
// socket closed: every further hello logged another refusal, and a failed proof got
|
|
196
|
+
// a second try.
|
|
197
|
+
let stage = 'hello';
|
|
198
|
+
let key = null;
|
|
199
|
+
let nonceE = '';
|
|
200
|
+
let nonceS = '';
|
|
201
|
+
let peer = '';
|
|
202
|
+
const timer = setTimeout(() => {
|
|
203
|
+
if (stage !== 'open')
|
|
204
|
+
ws.terminate();
|
|
205
|
+
}, this.handshakeMs);
|
|
206
|
+
const drop = () => {
|
|
207
|
+
stage = 'closed';
|
|
176
208
|
ws.close();
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
184
|
-
}, 5000);
|
|
209
|
+
};
|
|
210
|
+
const refuse = (code, message, extra = {}) => {
|
|
211
|
+
const err = { type: 'error', code, message, ...extra };
|
|
212
|
+
ws.send(JSON.stringify(err));
|
|
213
|
+
drop();
|
|
214
|
+
};
|
|
185
215
|
ws.on('message', (data) => {
|
|
216
|
+
if (stage === 'closed')
|
|
217
|
+
return;
|
|
186
218
|
let msg;
|
|
187
219
|
try {
|
|
188
220
|
msg = JSON.parse(String(data));
|
|
189
221
|
}
|
|
190
222
|
catch {
|
|
191
|
-
|
|
223
|
+
drop();
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
if (!msg || typeof msg !== 'object') {
|
|
227
|
+
drop();
|
|
192
228
|
return;
|
|
193
229
|
}
|
|
194
|
-
if (
|
|
195
|
-
if (msg.type
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
this.sessionToken = randomBytes(32).toString('hex');
|
|
199
|
-
this.client = ws;
|
|
200
|
-
const welcome = {
|
|
201
|
-
type: 'welcome',
|
|
202
|
-
protocol: BRIDGE_PROTOCOL,
|
|
203
|
-
serverVersion: this.serverVersion,
|
|
204
|
-
token: this.sessionToken,
|
|
205
|
-
};
|
|
206
|
-
ws.send(JSON.stringify(welcome));
|
|
207
|
-
this.log(`bridge: extension connected (${msg.extensionId} v${msg.extensionVersion})`);
|
|
230
|
+
if (stage === 'hello') {
|
|
231
|
+
if (msg.type !== 'hello') {
|
|
232
|
+
drop();
|
|
233
|
+
return;
|
|
208
234
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
ws.close();
|
|
235
|
+
peer = `${printable(msg.extensionId)} v${printable(msg.extensionVersion, 20)}`;
|
|
236
|
+
if (msg.protocol !== BRIDGE_PROTOCOL) {
|
|
237
|
+
const theirs = protocolNumber(String(msg.protocol));
|
|
238
|
+
const update = theirs > protocolNumber(BRIDGE_PROTOCOL) ? 'update @page2ai/mcp' : 'update the Page2AI extension';
|
|
239
|
+
this.log(`bridge: refused ${peer}: it speaks ${printable(msg.protocol)}, this server ${BRIDGE_PROTOCOL}; ${update}`);
|
|
240
|
+
refuse('PROTOCOL_MISMATCH', `this server speaks ${BRIDGE_PROTOCOL}`, { protocol: BRIDGE_PROTOCOL });
|
|
241
|
+
return;
|
|
217
242
|
}
|
|
243
|
+
const keyId = /^[0-9a-f]{16}$/.test(String(msg.keyId)) ? String(msg.keyId) : '(none)';
|
|
244
|
+
if (this.keys.length === 0) {
|
|
245
|
+
this.log(`bridge: Page2AI ${peer} (key ${keyId}) asked to connect, but this server has no ${BRIDGE_KEY_ENV}: ${HOW_TO_ADD_KEY}`);
|
|
246
|
+
refuse('NO_KEY', `this server has no ${BRIDGE_KEY_ENV}`);
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
key = this.keys.find((k) => k.id === keyId) ?? null;
|
|
250
|
+
if (!key) {
|
|
251
|
+
this.log(`bridge: refused ${peer}: its key ${keyId} is not in ${BRIDGE_KEY_ENV} ` +
|
|
252
|
+
`(${this.keys.map((k) => k.id).join(', ')}); add it, comma-separated, then restart the MCP client`);
|
|
253
|
+
refuse('UNKNOWN_KEY', `key ${keyId} is not in this server's ${BRIDGE_KEY_ENV}`);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (!isHex64(msg.nonceE)) {
|
|
257
|
+
drop();
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
nonceE = msg.nonceE;
|
|
261
|
+
nonceS = randomBytes(32).toString('hex');
|
|
262
|
+
stage = 'auth';
|
|
263
|
+
const challenge = {
|
|
264
|
+
type: 'challenge',
|
|
265
|
+
protocol: BRIDGE_PROTOCOL,
|
|
266
|
+
serverVersion: this.serverVersion,
|
|
267
|
+
nonceS,
|
|
268
|
+
proof: serverProof(key.bytes, this.port, nonceE, nonceS),
|
|
269
|
+
};
|
|
270
|
+
ws.send(JSON.stringify(challenge));
|
|
218
271
|
return;
|
|
219
272
|
}
|
|
220
|
-
if (
|
|
221
|
-
|
|
273
|
+
if (stage === 'auth') {
|
|
274
|
+
if (msg.type !== 'auth' || !proofMatches(clientProof(key.bytes, this.port, nonceS, nonceE), msg.proof)) {
|
|
275
|
+
this.log(`bridge: refused ${peer}: it named key ${key.id} but could not prove it`);
|
|
276
|
+
refuse('AUTH_FAILED', 'the proof does not match');
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
clearTimeout(timer);
|
|
280
|
+
this.handshakes.delete(ws);
|
|
281
|
+
if (this.isConnected()) {
|
|
282
|
+
this.log(`bridge: refused ${peer} (key ${key.id}): another browser holds the connection`);
|
|
283
|
+
refuse('ALREADY_CONNECTED', 'another browser is connected to this server');
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
stage = 'open';
|
|
287
|
+
this.client = ws;
|
|
288
|
+
const welcome = { type: 'welcome', protocol: BRIDGE_PROTOCOL, serverVersion: this.serverVersion };
|
|
289
|
+
ws.send(JSON.stringify(welcome));
|
|
290
|
+
this.log(`bridge: extension connected (${peer}, key ${key.id})`);
|
|
222
291
|
return;
|
|
223
292
|
}
|
|
293
|
+
// Only a connection that proved the key gets this far.
|
|
294
|
+
if (stage !== 'open')
|
|
295
|
+
return;
|
|
224
296
|
if (msg.type === 'ping') {
|
|
225
297
|
const pong = { type: 'pong' };
|
|
226
298
|
ws.send(JSON.stringify(pong));
|
|
227
299
|
return;
|
|
228
300
|
}
|
|
229
|
-
if (msg.type === 'result' &&
|
|
301
|
+
if (msg.type === 'result' && typeof msg.id === 'string') {
|
|
230
302
|
const pending = this.pending.get(msg.id);
|
|
231
303
|
if (pending) {
|
|
232
304
|
clearTimeout(pending.timer);
|
|
@@ -245,13 +317,13 @@ export class BridgeServer {
|
|
|
245
317
|
pending.resolve({
|
|
246
318
|
markdown: msg.markdown,
|
|
247
319
|
title: typeof msg.title === 'string' ? msg.title : '',
|
|
248
|
-
url:
|
|
320
|
+
url: msg.url,
|
|
249
321
|
charCount: msg.markdown.length,
|
|
250
322
|
});
|
|
251
323
|
}
|
|
252
324
|
return;
|
|
253
325
|
}
|
|
254
|
-
if (msg.type === 'error' &&
|
|
326
|
+
if (msg.type === 'error' && typeof msg.id === 'string' && msg.id) {
|
|
255
327
|
const pending = this.pending.get(msg.id);
|
|
256
328
|
if (pending) {
|
|
257
329
|
clearTimeout(pending.timer);
|
|
@@ -262,10 +334,10 @@ export class BridgeServer {
|
|
|
262
334
|
}
|
|
263
335
|
});
|
|
264
336
|
ws.on('close', () => {
|
|
265
|
-
clearTimeout(
|
|
337
|
+
clearTimeout(timer);
|
|
338
|
+
this.handshakes.delete(ws);
|
|
266
339
|
if (this.client === ws) {
|
|
267
340
|
this.client = null;
|
|
268
|
-
this.sessionToken = null;
|
|
269
341
|
this.log('bridge: extension disconnected');
|
|
270
342
|
// Its requests can no longer be answered: fail them now, not at their timeout.
|
|
271
343
|
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
|
|
87
|
-
// page_to_markdown
|
|
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
|
|
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
|
-
|
|
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)`);
|
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;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.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
|
+
"version": "0.6.1",
|
|
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.
|
|
3
|
+
"version": "0.6.1",
|
|
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.
|
|
11
|
+
"version": "0.6.1",
|
|
12
12
|
"packages": [
|
|
13
13
|
{
|
|
14
14
|
"registryType": "npm",
|
|
15
15
|
"identifier": "@page2ai/mcp",
|
|
16
|
-
"version": "0.
|
|
16
|
+
"version": "0.6.1",
|
|
17
17
|
"transport": {
|
|
18
18
|
"type": "stdio"
|
|
19
19
|
}
|