@branch42-labs/netraptor-mcp 0.3.3 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,6 +8,8 @@ Netraptor's local, read-only MCP server lets coding agents query API traffic cap
8
8
  2. Run it once, then enable the Local MCP server switch.
9
9
  3. Configure your MCP client.
10
10
 
11
+ Use the user-wide setup below so Netraptor is available in every workspace. Each person pairs their own browser and configures their own coding-agent account once. Start a new agent session after adding the server; the agent launches it automatically, so no manual background task or HTTP shim is needed.
12
+
11
13
  Codex:
12
14
 
13
15
  ```sh
@@ -18,10 +20,11 @@ codex mcp list
18
20
  Claude Code:
19
21
 
20
22
  ```sh
21
- claude mcp add netraptor -- npx -y @branch42-labs/netraptor-mcp
23
+ claude mcp add --scope user netraptor -- npx -y @branch42-labs/netraptor-mcp
24
+ claude mcp get netraptor
22
25
  ```
23
26
 
24
- Cursor (`~/.cursor/mcp.json` or the project's `.cursor/mcp.json`):
27
+ Cursor (use `~/.cursor/mcp.json` for every project):
25
28
 
26
29
  ```json
27
30
  {
@@ -36,12 +39,44 @@ Cursor (`~/.cursor/mcp.json` or the project's `.cursor/mcp.json`):
36
39
 
37
40
  The bridge listens only on `127.0.0.1:47321`. Set `NETRAPTOR_MCP_PORT` for the server and use the same port in extension settings to change it.
38
41
 
42
+ Codex, Claude Code, Cursor, and concurrent agent sessions share one authenticated local bridge. Closing one agent does not disconnect the others. The bridge exits five seconds after the last agent disconnects; a later agent starts it again. Stop any older running Netraptor MCP process once when upgrading to this shared-bridge version.
43
+
44
+ ## Query and follow live API traffic
45
+
46
+ Match the **Tab ID** and **Session #ID** shown in Netraptor's popup or panel. Before reading traffic, the agent must show them with the name, origin and capture state and ask you to confirm. If you already supplied an explicit ID, that counts as confirmation. If two or more live sessions are available, the agent must ask which one to use. Content tools require a `tabId` or `sessionId`; they never silently choose the newest capture. Prefer `tabId` for live recordings: it keeps following that tab when Stop/Start gives it a new Session #ID. Confirm again before switching.
47
+
48
+ With extension **0.5.0 or newer**, `list_sessions` reports `captureState`, `isLive`, `lastRequestAt` and `lastRequestId`. Live means an open tab has history enabled and its capture channel is responding; the old `status: running` flag alone does not prove this. Paused, inactive, history-off, disconnected and unverified channels are distinguished. Older extensions report unknown live state. An empty watch batch is an idle interval, not evidence that history is off. Compare the request cursor and last-call time after generating a known API call to verify traffic is arriving.
49
+
50
+ The **DevTools-only feed** includes all network resource types and is separate from saved API traffic. It has no MCP session ID. Use the saved Session #ID, rather than comparing its API-call count to the DevTools feed's total request count.
51
+
52
+ Turn on **Keep history for this site** in the extension and use your app normally. New fetch/XHR calls are saved continuously, even with DevTools closed, and MCP queries read those current records. The temporary DevTools live table is a separate capture source and is not exposed through MCP.
53
+
54
+ The live feed requires Chrome extension **0.4.0 or newer**. The other five tools continue to work with earlier extension versions while the update rolls out.
55
+
56
+ 1. `list_sessions` discovers saved sessions, their origins, checked capture state, last activity and IDs. Ask the user to confirm the correct Session #ID.
57
+ 2. `list_endpoints` lists its API endpoints; pass `tabId` or `sessionId` to keep the query scoped to the right app.
58
+ 3. `search` finds endpoints by URL, template, or GraphQL operation within the confirmed `tabId` or `sessionId`.
59
+ 4. `get_endpoint` returns schema and examples. Prefer its stable `key`, and pass `tabId` or `sessionId`.
60
+ 5. `get_request` reads headers and bodies for an example's request ID. Pass the confirmed `sessionId` too; a request from another session is rejected.
61
+ 6. `watch_requests` follows newly captured requests: start with `{ "tabId": 123, "afterId": 0 }`, then use each response's `nextCursor` as the next `afterId`. Drain `hasMore` pages before adding `waitMs: 5000` to wait for new calls. Empty batches are normal. Results contain request IDs and compact metadata; use `get_request` for bodies.
62
+
63
+ This live feed uses bounded long polling. It does not push unsolicited notifications into an agent conversation. Recording must be enabled for the site, and an agent must call the tools to read traffic. Choose a new session ID if you stop recording and begin a new session.
64
+
65
+ ## Connection troubleshooting
66
+
67
+ - **Pairing failed:** run the current browser's pairing command again, then use **Reconnect** in Netraptor Settings. Regenerating a code also requires pairing again. Pairing another browser replaces the secret stored on this computer.
68
+ - **Waiting for server:** launch or reconnect Netraptor in your coding agent. The extension's switch connects to the server; it does not start an agent process.
69
+ - **Tools missing after setup:** start a new agent session or reload its MCP configuration. In Codex, verify registration with `codex mcp list`.
70
+ - **Empty sessions / no new calls:** enable **Keep history for this site**, then reload or exercise the app. Queries cannot recover requests made before recording was enabled.
71
+ - **A session appears stuck:** check its exact ID, `captureState` and `lastRequestAt`, rather than selecting by name or highest count. An extension update can orphan the relay in an existing page; 0.5.0 repairs that relay without wrapping fetch/XHR again. If it reports `reload_required`, reload that page. `save_failed` means requests could not reach saved history; `unverified` means generate a new API call to verify the channel. Browsing another app in the same tab starts a new session ID.
72
+
39
73
  ## Security model
40
74
 
41
75
  - The listener binds to loopback only.
42
- - WebSocket upgrades are accepted only from a `chrome-extension://` Origin (web pages can't send one), and both sides must then prove the pairing secret with HMAC-SHA256 before any data flows.
76
+ - The browser-data WebSocket accepts only a `chrome-extension://` Origin. The separate agent channel requires the native client's Origin and an agent-specific HMAC proof. Both channels mutually authenticate before captured data flows.
43
77
  - Pairing codes look like `NR-772S-Y1F1-Q74G-R12P-8P1J-1CYS-D0` (128-bit secret). Pairing stores a derived secret in `~/.netraptor/mcp.json` with mode `0600`.
44
78
  - Every connection performs mutual HMAC-SHA256 challenge/response before captured data is accepted or sent.
79
+ - Agent processes authenticate separately to the shared bridge using an agent-specific HMAC role. A web page cannot use this channel.
45
80
  - Only one authenticated extension connection is active; a newer connection replaces it.
46
81
  - All exposed tools are read-only, and authorization/cookie headers are redacted.
47
82
 
package/dist/auth.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export declare const HANDSHAKE_TIMEOUT_MS = 10000;
2
2
  export declare function nonce(): string;
3
- export declare function hmac(secret: string, role: "server" | "extension", challenge: string): string;
4
- export declare function validHmac(secret: string, role: "server" | "extension", challenge: string, proof: unknown): boolean;
3
+ export declare function hmac(secret: string, role: "server" | "extension" | "agent", challenge: string): string;
4
+ export declare function validHmac(secret: string, role: "server" | "extension" | "agent", challenge: string, proof: unknown): boolean;
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEvE,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAE3C,MAAM,UAAU,KAAK;IACnB,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,MAAc,EAAE,IAA4B,EAAE,SAAiB;IAClF,OAAO,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;SAC1D,MAAM,CAAC,GAAG,IAAI,IAAI,SAAS,EAAE,CAAC;SAC9B,MAAM,CAAC,WAAW,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,MAAc,EACd,IAA4B,EAC5B,SAAiB,EACjB,KAAc;IAEd,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,OAAO,QAAQ,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,IAAI,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAChF,CAAC"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEvE,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAE3C,MAAM,UAAU,KAAK;IACnB,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,MAAc,EAAE,IAAsC,EAAE,SAAiB;IAC5F,OAAO,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;SAC1D,MAAM,CAAC,GAAG,IAAI,IAAI,SAAS,EAAE,CAAC;SAC9B,MAAM,CAAC,WAAW,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,MAAc,EACd,IAAsC,EACtC,SAAiB,EACjB,KAAc;IAEd,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,OAAO,QAAQ,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,IAAI,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAChF,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { PairingConfig } from "./pairing.js";
2
- export declare const NOT_CONNECTED = "Netraptor isn't connected. Open Chrome, then turn on Local MCP server in Netraptor Settings (Pro).";
2
+ export declare const NOT_CONNECTED = "Netraptor's browser extension isn't connected. Open Netraptor Settings \u2192 Local MCP server (Pro) and check its status. If it says Pairing failed, run this browser's current pairing command again, then click Reconnect. If it says Off, turn it on. Enable Keep history for this site to make new API calls available.";
3
3
  export declare const NOT_PAIRED = "Run `npx -y @branch42-labs/netraptor-mcp pair <code>` with the code from Netraptor Settings \u2192 Local MCP server.";
4
4
  export declare class ExtensionBridgeServer {
5
5
  private pairing;
@@ -7,12 +7,14 @@ export declare class ExtensionBridgeServer {
7
7
  private readonly port;
8
8
  private readonly requestTimeoutMs;
9
9
  private readonly loadPairing?;
10
+ private readonly onAgentsChanged?;
10
11
  private readonly http;
11
12
  private readonly wss;
12
13
  private active?;
13
14
  private counter;
14
15
  private readonly pending;
15
- constructor(pairing: PairingConfig | undefined, host?: string, port?: number, requestTimeoutMs?: number, loadPairing?: (() => Promise<PairingConfig | undefined>) | undefined);
16
+ private readonly agents;
17
+ constructor(pairing: PairingConfig | undefined, host?: string, port?: number, requestTimeoutMs?: number, loadPairing?: (() => Promise<PairingConfig | undefined>) | undefined, onAgentsChanged?: ((count: number) => void) | undefined);
16
18
  get address(): {
17
19
  host: string;
18
20
  port: number;
@@ -22,5 +24,7 @@ export declare class ExtensionBridgeServer {
22
24
  close(): Promise<void>;
23
25
  request(method: string, params: Record<string, unknown>): Promise<unknown>;
24
26
  private authenticate;
27
+ private agentRequest;
28
+ private rejectPending;
25
29
  private onMessage;
26
30
  }
@@ -3,7 +3,7 @@ import { WebSocketServer, WebSocket } from "ws";
3
3
  import { HANDSHAKE_TIMEOUT_MS, hmac, nonce, validHmac } from "./auth.js";
4
4
  import { parseMessage } from "./protocol.js";
5
5
  const REQUEST_TIMEOUT_MS = 10_000;
6
- export const NOT_CONNECTED = "Netraptor isn't connected. Open Chrome, then turn on Local MCP server in Netraptor Settings (Pro).";
6
+ export const NOT_CONNECTED = "Netraptor's browser extension isn't connected. Open Netraptor Settings → Local MCP server (Pro) and check its status. If it says Pairing failed, run this browser's current pairing command again, then click Reconnect. If it says Off, turn it on. Enable Keep history for this site to make new API calls available.";
7
7
  export const NOT_PAIRED = "Run `npx -y @branch42-labs/netraptor-mcp pair <code>` with the code from Netraptor Settings → Local MCP server.";
8
8
  export class ExtensionBridgeServer {
9
9
  pairing;
@@ -11,20 +11,28 @@ export class ExtensionBridgeServer {
11
11
  port;
12
12
  requestTimeoutMs;
13
13
  loadPairing;
14
+ onAgentsChanged;
14
15
  http;
15
16
  wss = new WebSocketServer({ noServer: true });
16
17
  active;
17
18
  counter = 0;
18
19
  pending = new Map();
20
+ agents = new Set();
19
21
  constructor(pairing, host = "127.0.0.1", port = 47321, requestTimeoutMs = REQUEST_TIMEOUT_MS,
20
22
  // Re-read on each connection so pairing after the agent started the server works.
21
- loadPairing) {
23
+ loadPairing, onAgentsChanged) {
22
24
  this.pairing = pairing;
23
25
  this.host = host;
24
26
  this.port = port;
25
27
  this.requestTimeoutMs = requestTimeoutMs;
26
28
  this.loadPairing = loadPairing;
27
- this.http = createServer((_request, response) => {
29
+ this.onAgentsChanged = onAgentsChanged;
30
+ this.http = createServer((request, response) => {
31
+ if (request.method === "GET" && request.url === "/health") {
32
+ response.writeHead(200, { "content-type": "application/json", "cache-control": "no-store" })
33
+ .end(JSON.stringify({ service: "netraptor-mcp", paired: Boolean(this.pairing), connected: this.connected }));
34
+ return;
35
+ }
28
36
  response.writeHead(404).end();
29
37
  });
30
38
  this.http.on("upgrade", async (request, socket, head) => {
@@ -32,12 +40,14 @@ export class ExtensionBridgeServer {
32
40
  this.pairing = await this.loadPairing().catch(() => this.pairing);
33
41
  // Web pages can't send a chrome-extension:// Origin; the HMAC handshake then
34
42
  // proves the extension holds the pairing secret.
35
- if (!this.pairing || !request.headers.origin?.startsWith("chrome-extension://")) {
43
+ const agent = request.url === "/agent" && request.headers.origin === "netraptor-mcp";
44
+ const extension = request.url === "/" && request.headers.origin?.startsWith("chrome-extension://");
45
+ if (!this.pairing || (!agent && !extension)) {
36
46
  socket.write("HTTP/1.1 403 Forbidden\r\nConnection: close\r\n\r\n");
37
47
  socket.destroy();
38
48
  return;
39
49
  }
40
- this.wss.handleUpgrade(request, socket, head, (ws) => this.authenticate(ws));
50
+ this.wss.handleUpgrade(request, socket, head, (ws) => this.authenticate(ws, agent));
41
51
  });
42
52
  }
43
53
  get address() {
@@ -86,7 +96,7 @@ export class ExtensionBridgeServer {
86
96
  this.pending.delete(id);
87
97
  reject(new Error(`Netraptor extension timed out after ${this.requestTimeoutMs / 1000}s.`));
88
98
  }, this.requestTimeoutMs);
89
- this.pending.set(id, { resolve, reject, timer });
99
+ this.pending.set(id, { socket: ws, resolve, reject, timer });
90
100
  ws.send(JSON.stringify({ id, method, params }), (error) => {
91
101
  if (!error)
92
102
  return;
@@ -96,7 +106,7 @@ export class ExtensionBridgeServer {
96
106
  });
97
107
  });
98
108
  }
99
- authenticate(ws) {
109
+ authenticate(ws, agent = false) {
100
110
  const pairing = this.pairing;
101
111
  if (!pairing) {
102
112
  ws.close(1008, "Not paired");
@@ -106,6 +116,11 @@ export class ExtensionBridgeServer {
106
116
  let clientChallenge;
107
117
  let serverProved = false;
108
118
  const timeout = setTimeout(() => ws.close(1008, "Handshake timed out"), HANDSHAKE_TIMEOUT_MS);
119
+ ws.on("error", () => ws.terminate());
120
+ ws.once("close", () => {
121
+ clearTimeout(timeout);
122
+ this.rejectPending(ws);
123
+ });
109
124
  const fail = () => ws.close(1008, "Authentication failed");
110
125
  const onHandshake = (raw) => {
111
126
  const message = parseMessage(raw);
@@ -120,13 +135,38 @@ export class ExtensionBridgeServer {
120
135
  }
121
136
  if (message?.type === "client-proof"
122
137
  && serverProved
123
- && validHmac(pairing.secret, "extension", serverChallenge, message.proof)) {
138
+ && validHmac(pairing.secret, agent ? "agent" : "extension", serverChallenge, message.proof)) {
124
139
  clearTimeout(timeout);
125
140
  ws.off("message", onHandshake);
141
+ if (agent) {
142
+ this.agents.add(ws);
143
+ this.onAgentsChanged?.(this.agents.size);
144
+ ws.once("close", () => {
145
+ this.agents.delete(ws);
146
+ this.onAgentsChanged?.(this.agents.size);
147
+ });
148
+ ws.on("message", (raw) => {
149
+ const request = parseMessage(raw);
150
+ if (request?.type === "ping") {
151
+ ws.send(JSON.stringify({ type: "pong" }));
152
+ }
153
+ else if (typeof request?.id === "string" && typeof request.method === "string") {
154
+ const params = request.params && typeof request.params === "object" && !Array.isArray(request.params)
155
+ ? request.params : {};
156
+ void this.agentRequest(ws, request.method, params).then((result) => { if (ws.readyState === WebSocket.OPEN)
157
+ ws.send(JSON.stringify({ id: request.id, result })); }, (error) => { if (ws.readyState === WebSocket.OPEN)
158
+ ws.send(JSON.stringify({ id: request.id, error: error instanceof Error ? error.message : String(error) })); });
159
+ }
160
+ });
161
+ ws.send(JSON.stringify({ type: "authenticated" }));
162
+ return;
163
+ }
126
164
  const previous = this.active;
127
165
  this.active = ws;
128
- if (previous && previous !== ws)
166
+ if (previous && previous !== ws) {
167
+ this.rejectPending(previous);
129
168
  previous.close(4001, "Replaced by newer connection");
169
+ }
130
170
  ws.on("message", (data) => this.onMessage(ws, data));
131
171
  ws.on("close", () => {
132
172
  if (this.active === ws)
@@ -140,6 +180,25 @@ export class ExtensionBridgeServer {
140
180
  ws.on("message", onHandshake);
141
181
  ws.send(JSON.stringify({ type: "server-challenge", challenge: serverChallenge }));
142
182
  }
183
+ async agentRequest(ws, method, params) {
184
+ // The agent can initialize before the extension's reconnect timer fires.
185
+ const deadline = Date.now() + 12_000;
186
+ while (!this.connected && ws.readyState === WebSocket.OPEN && Date.now() < deadline) {
187
+ await new Promise((resolve) => setTimeout(resolve, 100));
188
+ }
189
+ if (ws.readyState !== WebSocket.OPEN)
190
+ throw new Error(NOT_CONNECTED);
191
+ return this.request(method, params);
192
+ }
193
+ rejectPending(ws) {
194
+ for (const [id, pending] of this.pending) {
195
+ if (pending.socket !== ws)
196
+ continue;
197
+ clearTimeout(pending.timer);
198
+ this.pending.delete(id);
199
+ pending.reject(new Error(NOT_CONNECTED));
200
+ }
201
+ }
143
202
  onMessage(ws, raw) {
144
203
  const message = parseMessage(raw);
145
204
  if (message?.type === "ping") {
@@ -149,7 +208,7 @@ export class ExtensionBridgeServer {
149
208
  if (typeof message?.id !== "string")
150
209
  return;
151
210
  const pending = this.pending.get(message.id);
152
- if (!pending)
211
+ if (!pending || pending.socket !== ws)
153
212
  return;
154
213
  clearTimeout(pending.timer);
155
214
  this.pending.delete(message.id);
@@ -1 +1 @@
1
- {"version":3,"file":"bridge-server.js","sourceRoot":"","sources":["../src/bridge-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bridge-server.js","sourceRoot":"","sources":["../src/bridge-server.ts"],"names":[],"mappings":"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"}
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
2
- import { ExtensionBridgeServer } from "./bridge-server.js";
2
+ import { SharedBridgeClient, runSharedBridge } from "./shared-bridge.js";
3
3
  import { createMcpServer } from "./mcp-server.js";
4
4
  import { readPairingConfig, writePairingConfig } from "./pairing.js";
5
5
  function usage() {
@@ -26,23 +26,19 @@ export async function main(argv = process.argv.slice(2)) {
26
26
  process.stdout.write("Paired with Netraptor.\n");
27
27
  return;
28
28
  }
29
- if (argv.length > 0)
29
+ if (argv.length > 0 && !(argv.length === 1 && argv[0] === "bridge"))
30
30
  throw new Error(`Unknown command: ${argv[0]}\n\n${usage()}`);
31
31
  const rawPort = process.env.NETRAPTOR_MCP_PORT ?? "47321";
32
32
  const port = Number(rawPort);
33
33
  if (!Number.isInteger(port) || port < 1 || port > 65535) {
34
34
  throw new Error(`Invalid NETRAPTOR_MCP_PORT: ${rawPort}`);
35
35
  }
36
- const bridge = new ExtensionBridgeServer(await readPairingConfig(), "127.0.0.1", port, undefined, () => readPairingConfig());
37
- try {
38
- await bridge.listen();
39
- }
40
- catch (error) {
41
- if (error instanceof Error && "code" in error && error.code === "EADDRINUSE") {
42
- throw new Error(`Another netraptor-mcp is already listening on 127.0.0.1:${port} (possibly an orphaned instance). Stop it or set NETRAPTOR_MCP_PORT to a different port.`);
43
- }
44
- throw error;
45
- }
36
+ if (argv[0] === "bridge")
37
+ return runSharedBridge(port);
38
+ const bridge = new SharedBridgeClient(port);
39
+ // Tool discovery works before pairing; the first call can start the bridge after pairing.
40
+ if (await readPairingConfig())
41
+ await bridge.start();
46
42
  const mcp = createMcpServer(bridge);
47
43
  await mcp.connect(new StdioServerTransport());
48
44
  let closing = false;
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
@@ -10,30 +10,73 @@ function text(value) {
10
10
  }],
11
11
  };
12
12
  }
13
+ const target = {
14
+ tabId: z.number().int().positive().optional()
15
+ .describe("Browser Tab ID confirmed with the user (tabIds in list_sessions). Follows that tab's current recording."),
16
+ sessionId: z.number().int().positive().optional()
17
+ .describe("Session ID confirmed with the user; match Session #ID in Netraptor. Use for saved sessions no tab is recording."),
18
+ };
19
+ const hasTarget = ({ tabId, sessionId }) => tabId !== undefined || sessionId !== undefined;
20
+ const targetMessage = { message: "Provide the confirmed tabId or sessionId." };
13
21
  export function createMcpServer(bridge) {
14
- const server = new McpServer({ name: "netraptor", version });
22
+ const server = new McpServer({ name: "netraptor", version }, {
23
+ instructions: "Netraptor provides read-only access to saved API traffic. FIRST call list_sessions. Before reading session traffic, ask the user to confirm the browser tab (Tab ID from tabIds), Session #ID, name, origin and captureState exactly as shown in Netraptor. If the user already explicitly supplied that tab or session ID, treat it as confirmation. If two or more live sessions are available, ask which one to use; NEVER choose by newest timestamp or request count. For a live recording pass the confirmed tabId: it keeps following that tab when Stop/Start gives it a new Session #ID. Pass sessionId for saved sessions that no tab is recording. isLive/captureState report checked browser recording state; historical status=running alone does NOT mean live. Unknown/unverified requires checking, reload_required means reload the affected page, and an empty watch batch only means no new saved requests during the wait, not that history is disabled. list_sessions and all session responses include lastRequestAt/lastRequestId to verify activity. The DevTools-only feed is separate and unavailable through MCP. After confirmation use scoped search, get_endpoint and get_request. Follow traffic with watch_requests and nextCursor; drain hasMore then wait up to 5000ms. Reconfirm before switching tabs or sessions. Sensitive headers, URLs and top-level JSON fields are redacted; other body data may remain sensitive.",
24
+ });
25
+ const annotations = { readOnlyHint: true, destructiveHint: false, openWorldHint: false };
15
26
  const proxy = async (method, params) => {
16
27
  try {
17
- return text(await bridge.request(method, params));
28
+ const value = await bridge.request(method, params);
29
+ if (params.tabId !== undefined && (!value || typeof value !== "object" || !("tabId" in value) || value.tabId !== params.tabId)) {
30
+ return { ...text("Following a tab requires Netraptor Chrome extension 0.5.0 or newer. Update the extension, or pass the confirmed sessionId instead."), isError: true };
31
+ }
32
+ if (method === "get_request" && (!value || typeof value !== "object" || !("sessionId" in value) || value.sessionId !== params.sessionId)) {
33
+ return { ...text("This request does not belong to the confirmed session. Check list_sessions and select the correct sessionId before reading it."), isError: true };
34
+ }
35
+ if (method === "list_sessions" && Array.isArray(value)) {
36
+ return text(value.map((session) => session.captureState ? session : {
37
+ ...session, label: `Session #${session.id}`, source: "saved_api",
38
+ captureState: "unknown", isLive: false,
39
+ lastRequestAt: null, lastRequestId: null,
40
+ activityNotice: "This extension cannot verify live recording state. Update Netraptor to 0.5.0 or newer; do not infer live capture from status=running.",
41
+ }));
42
+ }
43
+ return text(value);
18
44
  }
19
45
  catch (error) {
20
- return { ...text(error instanceof Error ? error.message : String(error)), isError: true };
46
+ const message = error instanceof Error ? error.message : String(error);
47
+ const detail = method === "watch_requests" && message.includes("Unknown MCP method")
48
+ ? "Live request following requires Netraptor Chrome extension 0.4.0 or newer. Update the extension and reopen its settings. Existing list_sessions, list_endpoints, search, get_endpoint and get_request tools still work with earlier versions."
49
+ : message;
50
+ return { ...text(detail), isError: true };
21
51
  }
22
52
  };
23
53
  server.registerTool("list_sessions", {
24
- description: "List locally captured Netraptor sessions.",
54
+ annotations,
55
+ description: "Start here. Match Tab ID (tabIds), Session #ID, name and origin to the browser UI, and ask the user to confirm before reading traffic. If two or more sessions have isLive=true, ask which ID to use. Do not infer live state from status=running; check captureState and lastRequestAt. An empty list means no saved sessions exist yet, not proof that history is off.",
25
56
  inputSchema: z.object({}),
26
57
  }, () => proxy("list_sessions", {}));
58
+ server.registerTool("watch_requests", {
59
+ description: "Follow live captured API calls in one browser tab or session. Use list_sessions, check captureState/isLive and ask the user to confirm its Tab ID and Session #ID first. Prefer tabId for live recordings so Stop/Start in that tab is followed; the response session shows which Session #ID was read. Start afterId at 0, then pass nextCursor as afterId on each call. Drain hasMore pages before waiting. waitMs long-polls for up to 5000ms; an empty batch is normal and does not prove recording is disabled. The session metadata reports recording health and last saved activity. Requests are returned in ID order without repeats or skipped pages. Use get_request with id and the confirmed sessionId for headers and bodies. This is a bounded pull feed, not unsolicited push notifications.",
60
+ annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
61
+ inputSchema: z.object({
62
+ ...target,
63
+ afterId: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER).default(0)
64
+ .describe("Exclusive request cursor; use the previous nextCursor (initially 0)."),
65
+ limit: z.number().int().min(1).max(500).default(100),
66
+ waitMs: z.number().int().min(0).max(5_000).default(0),
67
+ }).refine(hasTarget, targetMessage),
68
+ }, (params) => proxy("watch_requests", params));
27
69
  server.registerTool("list_endpoints", {
28
- description: "List compact endpoint summaries, including stable keys and GraphQL operation names. Defaults to the most recent session and reports total before limiting.",
70
+ annotations,
71
+ description: "List compact endpoint summaries, including stable keys and GraphQL operation names. Requires the tabId or sessionId confirmed with the user and reports total before limiting.",
29
72
  inputSchema: z.object({
30
- sessionId: z.number().int().positive().optional()
31
- .describe("Captured session ID; defaults to the newest session."),
73
+ ...target,
32
74
  limit: z.number().int().min(1).max(1_000).default(200)
33
75
  .describe("Maximum endpoint summaries to return (default 200, max 1000)."),
34
- }),
76
+ }).refine(hasTarget, targetMessage),
35
77
  }, (params) => proxy("list_endpoints", params));
36
78
  server.registerTool("get_endpoint", {
79
+ annotations,
37
80
  description: "Get schema, parameters, bounded examples, and pages for one endpoint. Select by stable key, or by method + template and optional GraphQL operationName. Ambiguous GraphQL matches return the available operations.",
38
81
  inputSchema: z.object({
39
82
  key: z.string().min(1).optional()
@@ -44,26 +87,29 @@ export function createMcpServer(bridge) {
44
87
  .describe("Endpoint path template; required with method when key is omitted."),
45
88
  operationName: z.string().min(1).optional()
46
89
  .describe("GraphQL operation name used to disambiguate a shared method and path."),
47
- sessionId: z.number().int().positive().optional()
48
- .describe("Captured session ID; defaults to the newest session."),
90
+ ...target,
49
91
  maxExamples: z.number().int().min(0).max(5).default(2)
50
92
  .describe("Maximum deduplicated examples to return (default 2, max 5)."),
51
93
  maxBodyChars: z.number().int().min(100).max(20_000).default(4_000)
52
94
  .describe("Maximum characters per example request or response body (default 4000, max 20000)."),
53
- }).refine(({ key, method, template }) => Boolean(key || (method && template)), { message: "Provide key, or both method and template." }),
95
+ }).refine(({ key, method, template }) => Boolean(key || (method && template)), { message: "Provide key, or both method and template." }).refine(hasTarget, targetMessage),
54
96
  }, (params) => proxy("get_endpoint", params));
55
97
  server.registerTool("search", {
98
+ annotations,
56
99
  description: "Search captured endpoint templates, URLs, and GraphQL operation names. Returns compact results (key, method, template, GraphQL operation, calls, statuses; no params or URLs, use get_endpoint for those) and the total before limiting.",
57
100
  inputSchema: z.object({
58
101
  query: z.string().min(1).describe("Case-insensitive endpoint search text."),
102
+ ...target,
59
103
  limit: z.number().int().min(1).max(100).default(20)
60
104
  .describe("Maximum compact matches to return (default 20, max 100)."),
61
- }),
105
+ }).refine(hasTarget, targetMessage),
62
106
  }, (params) => proxy("search", params));
63
107
  server.registerTool("get_request", {
108
+ annotations,
64
109
  description: "Get one captured request with sensitive headers, URL parameters, and top-level JSON fields redacted and bodies bounded. Netraptor records from inside the page, so requestHeaders only contains headers the site's code set (not browser-added ones like cookies or user-agent). status 0 comes with failure: network-error, aborted, timeout, opaque (no-cors), or unknown (recorded before Netraptor tracked failures). bodyTruncated is true when either the capture or maxBodyChars cut a body.",
65
110
  inputSchema: z.object({
66
111
  id: z.number().int().positive().describe("Captured request ID."),
112
+ sessionId: z.number().int().positive().describe("Confirmed session ID; rejects requests from another capture."),
67
113
  maxBodyChars: z.number().int().min(100).max(200_000).default(20_000)
68
114
  .describe("Maximum characters for each request or response body (default 20000, max 200000)."),
69
115
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAG5B,MAAM,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAwB,CAAC;AAE7F,SAAS,IAAI,CAAC,KAAc;IAC1B,OAAO;QACL,OAAO,EAAE,CAAC;gBACR,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;aACzE,CAAC;KACH,CAAC;AACJ,CAAC;AAED,MAAM,MAAM,GAAG;IACb,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;SAC1C,QAAQ,CAAC,yGAAyG,CAAC;IACtH,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;SAC9C,QAAQ,CAAC,iHAAiH,CAAC;CAC/H,CAAC;AACF,MAAM,SAAS,GAAG,CAAC,EAAE,KAAK,EAAE,SAAS,EAA0C,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,CAAC;AACnI,MAAM,aAAa,GAAG,EAAE,OAAO,EAAE,2CAA2C,EAAE,CAAC;AAE/E,MAAM,UAAU,eAAe,CAAC,MAA8C;IAC5E,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE;QAC3D,YAAY,EAAE,83CAA83C;KAC74C,CAAC,CAAC;IACH,MAAM,WAAW,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAW,CAAC;IAClG,MAAM,KAAK,GAAG,KAAK,EAAE,MAAc,EAAE,MAA+B,EAAE,EAAE;QACtE,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACnD,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC/H,OAAO,EAAE,GAAG,IAAI,CAAC,oIAAoI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAC1K,CAAC;YACD,IAAI,MAAM,KAAK,aAAa,IAAI,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC,WAAW,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,SAAS,KAAK,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;gBACzI,OAAO,EAAE,GAAG,IAAI,CAAC,gIAAgI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YACtK,CAAC;YACD,IAAI,MAAM,KAAK,eAAe,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;oBAClE,GAAG,OAAO,EAAE,KAAK,EAAE,YAAY,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW;oBAChE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK;oBACtC,aAAa,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI;oBACxC,cAAc,EAAE,uIAAuI;iBACxJ,CAAC,CAAC,CAAC;YACN,CAAC;YACD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,MAAM,MAAM,GAAG,MAAM,KAAK,gBAAgB,IAAI,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC;gBAClF,CAAC,CAAC,+OAA+O;gBACjP,CAAC,CAAC,OAAO,CAAC;YACZ,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC5C,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE;QACnC,WAAW;QACX,WAAW,EAAE,0WAA0W;QACvX,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;KAC1B,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,CAAC;IAErC,MAAM,CAAC,YAAY,CAAC,gBAAgB,EAAE;QACpC,WAAW,EAAE,8wBAA8wB;QAC3xB,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE;QACjF,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,GAAG,MAAM;YACT,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;iBACrE,QAAQ,CAAC,sEAAsE,CAAC;YACnF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;YACpD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;SACtD,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC;KACpC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC;IAEhD,MAAM,CAAC,YAAY,CAAC,gBAAgB,EAAE;QACpC,WAAW;QACX,WAAW,EAAE,gLAAgL;QAC7L,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,GAAG,MAAM;YACT,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;iBACnD,QAAQ,CAAC,+DAA+D,CAAC;SAC7E,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC;KACpC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC;IAEhD,MAAM,CAAC,YAAY,CAAC,cAAc,EAAE;QAClC,WAAW;QACX,WAAW,EAAE,oNAAoN;QACjO,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;iBAC9B,QAAQ,CAAC,2DAA2D,CAAC;YACxE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;iBACjC,QAAQ,CAAC,0DAA0D,CAAC;YACvE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;iBACnC,QAAQ,CAAC,mEAAmE,CAAC;YAChF,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;iBACxC,QAAQ,CAAC,uEAAuE,CAAC;YACpF,GAAG,MAAM;YACT,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;iBACnD,QAAQ,CAAC,6DAA6D,CAAC;YAC1E,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;iBAC/D,QAAQ,CAAC,oFAAoF,CAAC;SAClG,CAAC,CAAC,MAAM,CACP,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,CAAC,EACnE,EAAE,OAAO,EAAE,2CAA2C,EAAE,CACzD,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC;KACnC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;IAE9C,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAE;QAC5B,WAAW;QACX,WAAW,EAAE,0OAA0O;QACvP,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,wCAAwC,CAAC;YAC3E,GAAG,MAAM;YACT,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;iBAChD,QAAQ,CAAC,0DAA0D,CAAC;SACxE,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC;KACpC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;IAExC,MAAM,CAAC,YAAY,CAAC,aAAa,EAAE;QACjC,WAAW;QACX,WAAW,EAAE,qeAAqe;QAClf,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;YAChE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8DAA8D,CAAC;YAC/G,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;iBACjE,QAAQ,CAAC,mFAAmF,CAAC;SACjG,CAAC;KACH,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,18 @@
1
+ /** Each stdio session owns an authenticated connection to one shared local bridge. */
2
+ export declare class SharedBridgeClient {
3
+ private readonly port;
4
+ private socket?;
5
+ private connecting?;
6
+ private heartbeat?;
7
+ private closed;
8
+ private counter;
9
+ private readonly pending;
10
+ constructor(port: number);
11
+ start(): Promise<void>;
12
+ private connect;
13
+ private attach;
14
+ request(method: string, params: Record<string, unknown>): Promise<unknown>;
15
+ close(): Promise<void>;
16
+ }
17
+ /** Internal daemon: exits shortly after the last stdio client disconnects. */
18
+ export declare function runSharedBridge(port: number): Promise<void>;
@@ -0,0 +1,199 @@
1
+ import { spawn } from "node:child_process";
2
+ import { fileURLToPath } from "node:url";
3
+ import WebSocket from "ws";
4
+ import { hmac, nonce, validHmac } from "./auth.js";
5
+ import { ExtensionBridgeServer, NOT_CONNECTED, NOT_PAIRED } from "./bridge-server.js";
6
+ import { readPairingConfig } from "./pairing.js";
7
+ import { parseMessage } from "./protocol.js";
8
+ /** Each stdio session owns an authenticated connection to one shared local bridge. */
9
+ export class SharedBridgeClient {
10
+ port;
11
+ socket;
12
+ connecting;
13
+ heartbeat;
14
+ closed = false;
15
+ counter = 0;
16
+ pending = new Map();
17
+ constructor(port) {
18
+ this.port = port;
19
+ }
20
+ async start() {
21
+ if (this.closed)
22
+ throw new Error(NOT_CONNECTED);
23
+ if (this.socket?.readyState === WebSocket.OPEN)
24
+ return;
25
+ if (this.connecting)
26
+ return this.connecting;
27
+ this.connecting = this.connect().finally(() => { this.connecting = undefined; });
28
+ return this.connecting;
29
+ }
30
+ async connect() {
31
+ const pairing = await readPairingConfig();
32
+ if (!pairing)
33
+ throw new Error(NOT_PAIRED);
34
+ const deadline = Date.now() + 4_000;
35
+ let spawned = false;
36
+ while (!this.closed) {
37
+ try {
38
+ await this.attach(pairing.secret);
39
+ return;
40
+ }
41
+ catch (error) {
42
+ // Never launch a competing bridge when the port already speaks another protocol.
43
+ if (error.code !== "ECONNREFUSED")
44
+ throw error;
45
+ if (!spawned) {
46
+ const daemon = spawn(process.execPath, [fileURLToPath(new URL("./cli.js", import.meta.url)), "bridge"], {
47
+ detached: true, stdio: "ignore", env: { ...process.env, NETRAPTOR_MCP_PORT: String(this.port) },
48
+ });
49
+ daemon.on("error", () => undefined);
50
+ daemon.unref();
51
+ spawned = true;
52
+ }
53
+ if (Date.now() >= deadline)
54
+ throw new Error(`Could not start Netraptor's shared bridge on 127.0.0.1:${this.port}. Check that this port is available.`);
55
+ await new Promise((resolve) => setTimeout(resolve, 50));
56
+ }
57
+ }
58
+ throw new Error(NOT_CONNECTED);
59
+ }
60
+ attach(secret) {
61
+ return new Promise((resolve, reject) => {
62
+ const ws = new WebSocket(`ws://127.0.0.1:${this.port}/agent`, { origin: "netraptor-mcp", handshakeTimeout: 2_000 });
63
+ const clientChallenge = nonce();
64
+ let serverChallenge = "";
65
+ let verified = false;
66
+ let authenticated = false;
67
+ const timer = setTimeout(() => { ws.terminate(); reject(new Error("Netraptor bridge handshake timed out.")); }, 3_000);
68
+ ws.on("error", (error) => {
69
+ if (error.code === "ECONNREFUSED")
70
+ reject(error);
71
+ else
72
+ reject(new Error(`Another server is already listening on 127.0.0.1:${this.port}, or the bridge is unresponsive. Stop older netraptor-mcp instances and reconnect.`));
73
+ });
74
+ ws.on("unexpected-response", (_request, response) => {
75
+ response.resume();
76
+ ws.terminate();
77
+ reject(new Error(`Another server is already listening on 127.0.0.1:${this.port}. Stop older netraptor-mcp instances and reconnect.`));
78
+ });
79
+ ws.on("close", () => {
80
+ clearTimeout(timer);
81
+ if (!authenticated)
82
+ reject(new Error("Netraptor bridge pairing failed. Run the current pairing command again."));
83
+ if (this.socket !== ws)
84
+ return;
85
+ this.socket = undefined;
86
+ if (this.heartbeat)
87
+ clearInterval(this.heartbeat);
88
+ for (const pending of this.pending.values()) {
89
+ clearTimeout(pending.timer);
90
+ pending.reject(new Error(NOT_CONNECTED));
91
+ }
92
+ this.pending.clear();
93
+ });
94
+ ws.on("message", (raw) => {
95
+ const message = parseMessage(raw);
96
+ if (!authenticated) {
97
+ if (message?.type === "server-challenge" && typeof message.challenge === "string") {
98
+ serverChallenge = message.challenge;
99
+ ws.send(JSON.stringify({ type: "client-challenge", challenge: clientChallenge }));
100
+ }
101
+ else if (message?.type === "server-proof" && validHmac(secret, "server", clientChallenge, message.proof)) {
102
+ verified = true;
103
+ ws.send(JSON.stringify({ type: "client-proof", proof: hmac(secret, "agent", serverChallenge) }));
104
+ }
105
+ else if (message?.type === "authenticated" && verified) {
106
+ clearTimeout(timer);
107
+ if (this.closed) {
108
+ ws.close();
109
+ reject(new Error(NOT_CONNECTED));
110
+ return;
111
+ }
112
+ authenticated = true;
113
+ this.socket = ws;
114
+ let lastPong = Date.now();
115
+ ws.on("message", (raw) => { if (parseMessage(raw)?.type === "pong")
116
+ lastPong = Date.now(); });
117
+ this.heartbeat = setInterval(() => {
118
+ if (Date.now() - lastPong >= 40_000)
119
+ ws.terminate();
120
+ else if (ws.readyState === WebSocket.OPEN)
121
+ ws.send(JSON.stringify({ type: "ping" }));
122
+ }, 20_000);
123
+ resolve();
124
+ }
125
+ else
126
+ ws.close(4008, "Authentication failed");
127
+ return;
128
+ }
129
+ if (typeof message?.id !== "string")
130
+ return;
131
+ const pending = this.pending.get(message.id);
132
+ if (!pending)
133
+ return;
134
+ this.pending.delete(message.id);
135
+ clearTimeout(pending.timer);
136
+ if (typeof message.error === "string")
137
+ pending.reject(new Error(message.error));
138
+ else
139
+ pending.resolve(message.result);
140
+ });
141
+ });
142
+ }
143
+ async request(method, params) {
144
+ await this.start();
145
+ const ws = this.socket;
146
+ if (!ws || ws.readyState !== WebSocket.OPEN)
147
+ throw new Error(NOT_CONNECTED);
148
+ const id = `${process.pid}-${++this.counter}`;
149
+ return new Promise((resolve, reject) => {
150
+ const timer = setTimeout(() => {
151
+ this.pending.delete(id);
152
+ reject(new Error("Netraptor bridge request timed out. Reconnect the MCP server and check the browser's connection status."));
153
+ ws.terminate();
154
+ }, 25_000);
155
+ this.pending.set(id, { resolve, reject, timer });
156
+ ws.send(JSON.stringify({ id, method, params }), (error) => {
157
+ if (!error)
158
+ return;
159
+ clearTimeout(timer);
160
+ this.pending.delete(id);
161
+ reject(error);
162
+ });
163
+ });
164
+ }
165
+ async close() {
166
+ this.closed = true;
167
+ if (this.heartbeat)
168
+ clearInterval(this.heartbeat);
169
+ this.socket?.terminate();
170
+ for (const pending of this.pending.values()) {
171
+ clearTimeout(pending.timer);
172
+ pending.reject(new Error(NOT_CONNECTED));
173
+ }
174
+ this.pending.clear();
175
+ }
176
+ }
177
+ /** Internal daemon: exits shortly after the last stdio client disconnects. */
178
+ export async function runSharedBridge(port) {
179
+ let idleTimer;
180
+ let closing = false;
181
+ const shutdown = () => {
182
+ if (closing)
183
+ return;
184
+ closing = true;
185
+ clearTimeout(idleTimer);
186
+ void bridge.close().finally(() => process.exit(0));
187
+ };
188
+ const onAgentsChanged = (count) => {
189
+ clearTimeout(idleTimer);
190
+ if (!count && !closing)
191
+ idleTimer = setTimeout(shutdown, 5_000);
192
+ };
193
+ const bridge = new ExtensionBridgeServer(await readPairingConfig(), "127.0.0.1", port, undefined, () => readPairingConfig(), onAgentsChanged);
194
+ await bridge.listen();
195
+ onAgentsChanged(0);
196
+ process.once("SIGINT", shutdown);
197
+ process.once("SIGTERM", shutdown);
198
+ }
199
+ //# sourceMappingURL=shared-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-bridge.js","sourceRoot":"","sources":["../src/shared-bridge.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@branch42-labs/netraptor-mcp",
3
- "version": "0.3.3",
3
+ "version": "0.5.0",
4
4
  "description": "Local read-only MCP bridge for Netraptor",
5
5
  "private": false,
6
6
  "type": "module",