@debugg-ai/debugg-ai-mcp 6.1.3 → 6.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -23,6 +23,30 @@ clear error on the first localhost-URL call, not a silent hang. Public-URL calls
23
23
  non-browser tool, and `test_suite {action:"run"}` (which uses its own dedicated tunnel and
24
24
  bypasses Caddy entirely) don't need it either way.
25
25
 
26
+ ## Testing a local app (no Tailscale, no port exposure)
27
+
28
+ Start your app on localhost, then pass the `http://localhost:<port>` URL straight to the tool. The MCP
29
+ opens its own DebuggAI tunnel (one per session, dialed through a local Caddy proxy) — do not expose the
30
+ port with Tailscale, ngrok, or anything else, and do not rewrite the URL to a tunnel hostname yourself.
31
+
32
+ ```json
33
+ probe_page { "targets": [{ "url": "http://localhost:4040" }] }
34
+ check_app_in_browser { "url": "http://localhost:4040", "description": "Open the home page and confirm the hero renders" }
35
+ ```
36
+
37
+ Verified 2026-11-10 against a Next.js dev server on `localhost:4040`: `probe_page` returned
38
+ `statusCode 200`, title, 0 console errors, and every asset request resolved via the tunnel.
39
+ Prerequisites: `DEBUGGAI_API_KEY` set for the MCP, the `caddy` binary available (see above), and the
40
+ app actually listening (a dead port fails fast with `LocalServerUnreachable`). Several pages on the
41
+ same port can share one `probe_page` call; mixing ports in one call works but runs serially.
42
+
43
+ `TunnelTrafficBlocked` means the tunnel came up but the health probe through it got no valid response. First
44
+ check you are on the latest MCP (`npx -y @debugg-ai/debugg-ai-mcp@latest`; a stale pinned version is the usual
45
+ cause), then that your dev server answers a plain `curl http://127.0.0.1:<port>/` and does not reject unknown
46
+ `Host` headers (tunnel requests carry the tunnel hostname; a gateway that routes by `Host` needs a catch-all).
47
+ Verified 2026-11-10: servers bound to `127.0.0.1` only (IPv4 Caddy gateways on :4040 and :4043) probe fine via
48
+ `http://localhost:<port>` and `http://127.0.0.1:<port>`.
49
+
26
50
  Get an API key at [debugg.ai](https://debugg.ai), then add to your MCP client config:
27
51
 
28
52
  ```json
@@ -101,10 +101,13 @@ export async function probeTunnelHealth(tunnelUrl, opts = {}) {
101
101
  const timeoutMs = opts.timeoutMs ?? 5000;
102
102
  const started = Date.now();
103
103
  let last;
104
+ let allClosed = true;
104
105
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
105
106
  const { result, retryable } = await probeOverControlChannel(tunnelUrl, timeoutMs, started);
106
107
  if (!retryable)
107
108
  return result;
109
+ if (!result.detail?.endsWith(' CLOSED'))
110
+ allClosed = false;
108
111
  last = result;
109
112
  if (attempt < maxAttempts) {
110
113
  await sleep(backoff[attempt - 1] ?? backoff[backoff.length - 1] ?? 150);
@@ -112,6 +115,14 @@ export async function probeTunnelHealth(tunnelUrl, opts = {}) {
112
115
  }
113
116
  // Ladder exhausted on a transient error — the tunnel never came up. Report
114
117
  // it: "not ready" that never becomes ready IS unhealthy.
118
+ //
119
+ // A control channel CLOSED on every attempt means the tunnel has no live
120
+ // session at all (a reconnect that never lands, or the transport forgot the
121
+ // tunnel while the manager still holds it). It can never serve a request, so
122
+ // flag it for eviction — otherwise every later call reuses the corpse and
123
+ // fails identically until the MCP process restarts.
124
+ if (allClosed && last)
125
+ last.tunnelErrorCode = 'CONTROL_CHANNEL_CLOSED';
115
126
  return last;
116
127
  }
117
128
  // ─ Control-channel probe ─────────────────────────────────────────────────────
@@ -69,6 +69,11 @@ const logger = new Logger({ module: 'tunnelDisposition' });
69
69
  const ENDPOINT_GONE_CODES = Object.freeze([
70
70
  'DEBUGG_TUNNEL_OFFLINE',
71
71
  'DEBUGG_TUNNEL_UNKNOWN',
72
+ // Client-side verdict, not a server marker: probeTunnelHealth saw the tunnel's
73
+ // own control channel CLOSED on every attempt of its ladder, i.e. there is no
74
+ // session left to carry traffic. Keeping it makes every later call fail the
75
+ // same way (the crochets build lead's "stuck at CLOSED" report).
76
+ 'CONTROL_CHANNEL_CLOSED',
72
77
  ]);
73
78
  const ENDPOINT_GONE_LOOKUP = new Set(ENDPOINT_GONE_CODES);
74
79
  /** The allowlist, as an immutable list. Read-only by construction. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@debugg-ai/debugg-ai-mcp",
3
- "version": "6.1.3",
3
+ "version": "6.1.4",
4
4
  "description": "Zero-Config, Fully AI-Managed End-to-End Testing for all code gen platforms.",
5
5
  "type": "module",
6
6
  "caddy": "2.11.3",