@choonkeat/agent-reverse-proxy 0.1.0 → 0.1.2

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 ADDED
@@ -0,0 +1,98 @@
1
+ # agent-reverse-proxy
2
+
3
+ A reverse proxy that sits in front of your web app, injecting debug instrumentation and exposing [MCP](https://modelcontextprotocol.io/) tools so AI agents can inspect the running page — query DOM elements, capture console logs, errors, and network requests.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npx @choonkeat/agent-reverse-proxy --help
9
+ ```
10
+
11
+ Or install globally:
12
+
13
+ ```bash
14
+ npm install -g @choonkeat/agent-reverse-proxy
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ```bash
20
+ # Proxy requests to your app on port 3000 (default)
21
+ agent-reverse-proxy
22
+
23
+ # Specify a different app port
24
+ agent-reverse-proxy --app-port 8080
25
+
26
+ # Specify the proxy port (default: 20000 + app-port)
27
+ agent-reverse-proxy --proxy-port 9000
28
+
29
+ # Plain reverse proxy, no debug script injection
30
+ agent-reverse-proxy --no-inject
31
+
32
+ # HTTP-only mode (no stdio MCP transport)
33
+ agent-reverse-proxy --no-stdio
34
+
35
+ # Custom tool prefix (default: "proxied")
36
+ agent-reverse-proxy --tool-prefix preview
37
+ ```
38
+
39
+ The proxy starts on `localhost:23000` (by default) and forwards to your app on `localhost:3000`. HTML responses get a small debug script injected that captures console output, errors, and network activity.
40
+
41
+ ## How it works
42
+
43
+ ```
44
+ Browser ──► agent-reverse-proxy (:23000) ──► Your app (:3000)
45
+
46
+ ├── Injects debug script into HTML responses
47
+ ├── Captures console.log/warn/error/info/debug
48
+ ├── Captures fetch() and XMLHttpRequest
49
+ ├── Captures uncaught errors and promise rejections
50
+ ├── Tracks SPA navigation (pushState, popstate)
51
+ └── Exposes MCP tools for AI agents
52
+ ```
53
+
54
+ ## MCP tools
55
+
56
+ The proxy registers two MCP tools (prefixed with `--tool-prefix`, default `proxied`):
57
+
58
+ ### `proxied_browser_snapshot`
59
+
60
+ Query DOM elements by CSS selector. Returns text content, inner HTML, visibility, and bounding rect.
61
+
62
+ ```json
63
+ { "selector": "h1" }
64
+ ```
65
+
66
+ ### `proxied_browser_console_messages`
67
+
68
+ Listen for console output, errors, and network requests for a specified duration (1–30 seconds).
69
+
70
+ ```json
71
+ { "duration_seconds": 5 }
72
+ ```
73
+
74
+ ## MCP resources
75
+
76
+ - `proxied-browser://reference` — How the proxy works: tools, message types, port configuration
77
+ - `proxied-browser://help` — Debugging workflow and tips
78
+
79
+ ## Port configuration
80
+
81
+ | Environment variable | Flag | Default |
82
+ |---|---|---|
83
+ | `APP_PORT` or `PORT` | `--app-port` | 3000 |
84
+ | `PROXY_PORT` | `--proxy-port` | 20000 + app port |
85
+
86
+ ## Features
87
+
88
+ - Reverse proxies HTTP and WebSocket connections
89
+ - Injects debug script into HTML responses (handles gzip-encoded responses)
90
+ - Modifies Content-Security-Policy headers to allow debug script and WebSocket
91
+ - Strips `Domain` from `Set-Cookie` headers so cookies work through the proxy
92
+ - Auto-upgrades `ws://` to `wss://` on HTTPS pages (with warning banner)
93
+ - Shows a "waiting for app" page with auto-retry when the app isn't running
94
+ - Supports both stdio and HTTP MCP transports
95
+
96
+ ## License
97
+
98
+ MIT
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { spawnSync } from "child_process";
3
+ import { spawnSync, execFileSync } from "child_process";
4
4
  import { createRequire } from "module";
5
5
  import { existsSync, chmodSync } from "fs";
6
6
  import { dirname, join } from "path";
@@ -34,27 +34,50 @@ if (!platform || !arch) {
34
34
  const pkgName = `@choonkeat/agent-reverse-proxy-${platform}-${arch}`;
35
35
  const binName = process.platform === "win32" ? "agent-reverse-proxy.exe" : "agent-reverse-proxy";
36
36
 
37
- let binPath;
38
- try {
39
- const pkgDir = dirname(require.resolve(`${pkgName}/package.json`));
40
- binPath = join(pkgDir, "bin", binName);
41
- } catch {
42
- // Fallback: check for local build in npm-platforms/ (development)
37
+ function resolveBinPath() {
38
+ try {
39
+ const pkgDir = dirname(require.resolve(`${pkgName}/package.json`));
40
+ return join(pkgDir, "bin", binName);
41
+ } catch {
42
+ return null;
43
+ }
44
+ }
45
+
46
+ let binPath = resolveBinPath();
47
+
48
+ // optionalDependencies may not be installed (e.g. npx) — install on demand
49
+ if (!binPath) {
50
+ try {
51
+ console.error(`Installing ${pkgName}...`);
52
+ execFileSync("npm", ["install", "--no-save", pkgName], {
53
+ stdio: "inherit",
54
+ cwd: join(__dirname, ".."),
55
+ });
56
+ binPath = resolveBinPath();
57
+ } catch {
58
+ // ignore — fall through to local/error path
59
+ }
60
+ }
61
+
62
+ // Fallback: check for local build in npm-platforms/ (development)
63
+ if (!binPath) {
43
64
  const localPath = join(__dirname, "..", "npm-platforms", `${platform}-${arch}`, "bin", binName);
44
65
  if (existsSync(localPath)) {
45
66
  binPath = localPath;
46
- } else {
47
- console.error(
48
- `Could not find package ${pkgName}.\n` +
49
- `Make sure it is installed — this usually means your platform is supported\n` +
50
- `but the optional dependency was not installed.\n\n` +
51
- `Try: npm install ${pkgName}\n` +
52
- `Or run: npx @choonkeat/agent-reverse-proxy`
53
- );
54
- process.exit(1);
55
67
  }
56
68
  }
57
69
 
70
+ if (!binPath) {
71
+ console.error(
72
+ `Could not find package ${pkgName}.\n` +
73
+ `Make sure it is installed — this usually means your platform is supported\n` +
74
+ `but the optional dependency was not installed.\n\n` +
75
+ `Try: npm install ${pkgName}\n` +
76
+ `Or run: npx @choonkeat/agent-reverse-proxy`
77
+ );
78
+ process.exit(1);
79
+ }
80
+
58
81
  if (!existsSync(binPath)) {
59
82
  console.error(`Binary not found at ${binPath}`);
60
83
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@choonkeat/agent-reverse-proxy",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "MCP server with reverse proxy and debug instrumentation for app preview",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,11 +16,11 @@
16
16
  },
17
17
  "license": "MIT",
18
18
  "optionalDependencies": {
19
- "@choonkeat/agent-reverse-proxy-linux-x64": "0.1.0",
20
- "@choonkeat/agent-reverse-proxy-linux-arm64": "0.1.0",
21
- "@choonkeat/agent-reverse-proxy-darwin-x64": "0.1.0",
22
- "@choonkeat/agent-reverse-proxy-darwin-arm64": "0.1.0",
23
- "@choonkeat/agent-reverse-proxy-win32-x64": "0.1.0",
24
- "@choonkeat/agent-reverse-proxy-win32-arm64": "0.1.0"
19
+ "@choonkeat/agent-reverse-proxy-linux-x64": "0.1.2",
20
+ "@choonkeat/agent-reverse-proxy-linux-arm64": "0.1.2",
21
+ "@choonkeat/agent-reverse-proxy-darwin-x64": "0.1.2",
22
+ "@choonkeat/agent-reverse-proxy-darwin-arm64": "0.1.2",
23
+ "@choonkeat/agent-reverse-proxy-win32-x64": "0.1.2",
24
+ "@choonkeat/agent-reverse-proxy-win32-arm64": "0.1.2"
25
25
  }
26
26
  }