You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* feat(webhook-proxy): inbound-request debug logging + connector docs
- Add `debug_logging` toggle (visible on the main Configuration page); logs
each inbound request to the HA log before the OAuth gate so the 401
discovery probe is captured too. Confirms whether a client is reaching the
server. The integration logger is raised to INFO while on.
- Document the Claude.ai web flow (add connector -> Connect -> Allow) and a
public-reachability check across the addon DOCS, setup site, and FAQ.
- Bump the addon to 1.2.0 and add a backfilled CHANGELOG.md.
Closes#1627
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test(webhook-proxy): debug_logging tests; sync manifest version; keep OFF-path hass.data shape
- Bump integration manifest.json to 1.2.0 to match config.yaml (the addon/
integration version-match guard used by start.py update detection).
- Add the debug_logging key to hass.data only when enabled, keeping the
OFF-path shape identical to baseline (TestOAuthOffPreservesBehavior).
- Add config-structure + TestDebugLogging tests (off/on hass.data shape,
inbound-request logging); apply ruff format.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(webhook-proxy): address review (request.remote, symmetric logger guard, +tests)
- Log the inbound source from request.remote (the HA-validated client IP)
rather than the spoofable X-Forwarded-For header.
- Raise the integration logger to INFO only when the effective level is less
verbose, and on the OFF path only undo an INFO we ourselves raised — never
clobber a user's explicit `logger:` level in either direction.
- Add tests: 401-before-gate inbound logging, upstream-response log line, and
all three logger-level branches (with an autouse logger-level reset).
- Revert an unrelated cosmetic ruff reformat of oauth.py swept in by a broad
`ruff format`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* ci(webhook-proxy): type-check the mcp_proxy integration under mypy
CI's mypy step only covered start.py, leaving the mcp_proxy integration
package untyped on every platform (not a Windows quirk — it was never in the
mypy command). Bring it under the same gate as custom_components/ and fix the
gaps that surfaced:
- pr.yml: mypy the whole homeassistant-addon-webhook-proxy/ dir, not just
start.py.
- config_flow.py: annotate the flow methods and `# type: ignore[call-arg]` the
`domain=` subclass kwarg, mirroring custom_components/ha_mcp_tools.
- oauth.py / __init__.py: fix two no-any-return warnings.
- pyproject.toml: add yarl to the ignore_missing_imports override (it ships
with aiohttp, already ignored).
- Restore the repo-wide ruff format on oauth.py.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: kingpanther13 <kingpanther13@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/FAQ.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -61,6 +61,8 @@ You can also start a new conversation and ask Claude if it can see your Home Ass
61
61
62
62
This is a known Claude.ai behavior that affects all MCP servers, not just ha-mcp.
63
63
64
+
**If it genuinely won't connect** (not just the transient handshake error above): Claude.ai connects from Anthropic's servers, so the MCP URL must be reachable from the public internet — not just your LAN. A URL that works in Claude Code or a local browser can still be unreachable for Claude.ai web. Open the URL on your **phone with Wi-Fi off** (cellular): if it doesn't load there, it isn't publicly reachable (DNS / port-forward / TLS / reverse-proxy) and Claude.ai can't reach it either. Also make sure you clicked **Connect** on the connector (and, with OAuth enabled, **Allow** on the consent page) — adding the connector alone does not complete the connection.
65
+
64
66
### "Terminating session: None" in server logs
65
67
66
68
**This is normal.** ha-mcp runs in stateless HTTP mode, which means each request creates and discards a temporary session. The `Terminating session: None` log message is the MCP SDK reporting this routine cleanup — the connection stays active.
Copy file name to clipboardExpand all lines: homeassistant-addon-webhook-proxy/DOCS.md
+38-2Lines changed: 38 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,6 +23,14 @@ This addon enables remote access to your HA MCP Server through any reverse proxy
23
23
```
24
24
5.**Paste the URL** into your MCP client (Claude Desktop, Claude.ai, Open WebUI, etc.)
25
25
26
+
### Connecting from Claude.ai (web)
27
+
28
+
1. In Claude.ai, go to **Settings → Connectors → Add custom connector**, give it a name, paste the remote URL, and click **Add**.
29
+
2.**Click _Connect_ on the new connector.** This step is required — adding the connector does not connect it. With OAuth enabled this opens the consent page; click **Allow** to finish. (With OAuth off there is no consent page and it connects directly.)
30
+
3. Claude.ai may briefly show *"Couldn't reach the MCP server"* — this is often a harmless artifact of the initial handshake. Check whether the connector actually shows as connected before assuming it failed.
31
+
32
+
> **Reachability check:** Claude.ai connects from Anthropic's servers, not from your computer — so the URL must be reachable from the public internet, not just your LAN. If a connection won't establish, open the remote URL on your **phone with Wi-Fi turned off** (cellular only). If it doesn't load there, the URL isn't publicly reachable (a DNS, port-forward, TLS, or reverse-proxy problem) and Claude.ai can't reach it either — fix that first.
33
+
26
34
> **Note:** If something doesn't seem to work after restarting HA, try restarting the addon as well.
27
35
28
36
## Configuration
@@ -36,8 +44,9 @@ This addon enables remote access to your HA MCP Server through any reverse proxy
36
44
|`oauth_client_id`| OAuth Client ID (auto-generated if blank) |`""`|
37
45
|`oauth_client_secret`| OAuth Client Secret (auto-generated if blank) |`""`|
38
46
|`regenerate_oauth_creds`| One-shot: wipe stored OAuth creds and generate fresh ones on next start |`false`|
47
+
|`debug_logging`|**Beta.** Log every inbound request to the Home Assistant log to confirm a client is reaching the server |`false`|
39
48
40
-
> The OAuth options are hidden by default. Toggle **Show unused optional configuration options** at the bottom of the addon's Configuration tab to reveal them.
49
+
> The OAuth options are hidden by default. Toggle **Show unused optional configuration options** at the bottom of the addon's Configuration tab to reveal them.`debug_logging` is shown on the main Configuration page (it is not one of the hidden options).
41
50
42
51
### Auto-detection
43
52
@@ -132,7 +141,7 @@ The generated values are persisted at `/data/oauth_creds.json` inside the addon,
132
141
133
142
### End-to-end flow (what happens when Claude.ai connects)
134
143
135
-
When OAuth is enabled and you paste the webhook URL + Client ID + Client Secret into Claude.ai's connector setup, here's what happens:
144
+
When OAuth is enabled and you paste the webhook URL + Client ID + Client Secret into Claude.ai's connector setup, here's what happens after you click **Connect** on the connector:
136
145
137
146
1.**Claude.ai's browser session** is redirected to `https://<your-host>/authorize?response_type=code&client_id=...&redirect_uri=...&code_challenge=...&code_challenge_method=S256&state=...&resource=https://<your-host>/api/webhook/<id>`.
138
147
2. The addon serves a **consent page** (Allow / Deny) showing the redirect destination so you can verify it's Claude.ai's callback URL before proceeding.
@@ -168,6 +177,24 @@ What stops an attacker who can reach the consent page from gaining access:
168
177
- If you suspect it has leaked, **rotate it immediately** using one of the three rotation methods above. After rotation, the old Client Secret stops working — any tokens previously issued will fail at refresh, forcing the client to re-do the OAuth flow with the new credentials.
169
178
- If you can't tell whether it leaked but want a clean slate (e.g., after sharing logs for debugging, after a migration), rotating proactively is cheap: flip **Regenerate OAuth Credentials on Next Start**, restart, paste the new credentials into Claude.ai. Takes ~30 seconds.
170
179
180
+
### Debugging connections (log inbound requests)
181
+
182
+
If a client (e.g. Claude.ai) can't connect and you can't tell whether its requests are even reaching Home Assistant, turn on **Log inbound requests** (the `debug_logging` option on the main Configuration page) and **restart the addon**.
183
+
184
+
When it's on, every request that hits the webhook is logged to the **Home Assistant log** — *not* this addon's log, because requests reach Home Assistant directly rather than passing through the addon process. View them at **Settings → System → Logs** (or filter for `mcp_proxy`). Each line shows the method, a masked webhook path, the source address, whether an `Authorization` header was present, and the upstream response status:
185
+
186
+
```
187
+
MCP Proxy [inbound]: POST /api/webhook/mcp_3e... from 203.0.113.4 (Authorization header: present)
-**You see inbound lines** → the client is reaching the server; the problem is downstream (auth, the client's config, or the MCP server itself).
194
+
-**You see nothing** → the request never arrived. The problem is network reachability — the public URL, DNS, TLS, or your reverse proxy — not this addon. See the reachability check under [Setup](#connecting-from-claudeai-web).
195
+
196
+
Turn it back off for normal operation (restart the addon after changing it).
197
+
171
198
## How it works
172
199
173
200
1. The addon installs a lightweight `mcp_proxy` custom integration into Home Assistant
@@ -203,6 +230,15 @@ If the `mcp_proxy` integration doesn't appear in Settings > Devices & Services:
203
230
1. Restart Home Assistant (Settings > System > Restart)
204
231
2. The addon will start automatically and retry setup
205
232
233
+
### Claude.ai says "Couldn't reach the MCP server"
234
+
235
+
Two cases:
236
+
237
+
1.**It actually connected.** Claude.ai sometimes shows this during the initial handshake even though the connector ends up working. Check whether the connector shows as connected before assuming failure.
238
+
2.**It genuinely can't reach the URL.** Claude.ai connects from Anthropic's servers, so the URL must be reachable from the public internet — not just your LAN. Open the remote URL on your **phone with Wi-Fi off** (cellular): if it doesn't load, the URL isn't publicly reachable (DNS / port-forward / TLS / reverse-proxy) and Claude.ai can't reach it either. To confirm whether requests are arriving at all, enable **Log inbound requests** (see [Debugging connections](#debugging-connections-log-inbound-requests)).
239
+
240
+
> **Note:** A connection working in Claude Code or a local browser but **not** in Claude.ai web is the classic signature of this — those reach your box over the LAN, while Claude.ai reaches it from the public internet.
241
+
206
242
## Disabling / Uninstalling
207
243
208
244
-**Stopping** the addon is safe — the webhook URL stays the same and resumes working when the addon is restarted
0 commit comments