Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion homeassistant-addon-webhook-proxy-dev/config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: "Nabu Casa - Webhook Proxy for HA MCP (Dev)"
description: "DEV CHANNEL (unstable) — remote access proxy via Nabu Casa or any reverse proxy. Cannot run alongside the stable Webhook Proxy add-on."
version: "3.0.2.dev2"
version: "3.0.3.dev1"
slug: "ha_mcp_webhook_proxy_dev"
url: "https://github.com/homeassistant-ai/ha-mcp"
stage: experimental
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
"dependencies": ["webhook"],
"documentation": "https://github.com/homeassistant-ai/ha-mcp",
"iot_class": "local_push",
"version": "3.0.2.dev2"
"version": "3.0.3.dev1"
}
16 changes: 16 additions & 0 deletions homeassistant-addon-webhook-proxy/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

<!-- version list -->

## v3.0.2 (2026-08-24)

### Bug Fixes

- In `ha_auth` mode, loopback-callback and multi-origin registered clients no
longer have to sign in again whenever Home Assistant's 30-minute access token
expires. Refresh tokens now retain the exact client identity used during
authorization; sessions created before this update may need one final
reauthorization.

- Revoking one of these refresh tokens now revokes the underlying Home
Assistant grant instead of returning success while leaving it active. OAuth
discovery advertises a scoped revocation endpoint for `ha_auth`, and
temporary forwarding failures return `503` with retry guidance.



## v3.0.1 (2026-08-18)

Expand Down
3 changes: 2 additions & 1 deletion homeassistant-addon-webhook-proxy/DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,12 @@ All three behaviors advertise proxy-owned endpoints under `/api/mcp_proxy/oauth`
- `/api/mcp_proxy/oauth/authorize` — mode-dispatched authorization endpoint
- `/api/mcp_proxy/oauth/token` — mode-dispatched token endpoint
- `/api/mcp_proxy/oauth/register` — stateless DCR endpoint, advertised in `ha_auth` and none mode
- `/api/mcp_proxy/oauth/revoke` — RFC 7009 revocation endpoint, advertised and served in `ha_auth` mode only (404 elsewhere)

The same authorize/token URLs behave according to the active mode:

- **None mode:** accepts any valid HTTPS or RFC 8252 loopback redirect, auto-approves without a page, and issues a cosmetic token. DCR registrations advertise only the authorization-code grant.
- **`ha_auth`:** validates CIMD or signed DCR identities before sending the browser/token exchange into Home Assistant core. DCR advertises refresh only when the registered redirects have one reproducible web origin.
- **`ha_auth`:** validates CIMD or signed DCR identities before sending the browser/token exchange into Home Assistant core. DCR advertises refresh for every registration: a forwarded token response comes back with its refresh token wrapped in a signed envelope naming the identity core bound it to, so loopback-callback and multi-origin clients refresh without re-authorizing. The proxy also fronts token revocation on its own scoped revocation endpoint, so a wrapped refresh token is unwrapped before Home Assistant sees it and is really revoked. Revocation accepts a wrapped token even when its signature no longer verifies — after the signing key rotates, which is what removing and re-adding the integration does — because possession of a token is the only authorization revoking it needs, and Home Assistant's own revocation endpoint is anonymous and idempotent. Sessions authorized before this version carry no envelope: they re-authorize once, then refresh normally.
- **`legacy`:** serves the existing consent and credentialed token flow on the scoped URLs. The host-root `/authorize` and `/token` routes remain compatibility aliases but are not advertised; legacy does not advertise DCR.

**Hosted Claude environment requirements:** Hosted Claude surfaces reach your server from Anthropic's backend, not from your browser. Three environment rules apply that no server-side setting can work around:
Expand Down
2 changes: 1 addition & 1 deletion homeassistant-addon-webhook-proxy/config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: "Nabu Casa - Webhook Proxy for HA MCP"
description: "Remote access proxy via Nabu Casa or any reverse proxy (Cloudflare, DuckDNS, nginx)"
version: "3.0.1"
version: "3.0.2"
slug: "ha_mcp_webhook_proxy"
url: "https://github.com/homeassistant-ai/ha-mcp"
arch:
Expand Down
9 changes: 9 additions & 0 deletions homeassistant-addon-webhook-proxy/mcp_proxy/auth_native.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,21 @@ def authorization_server_document(base: str) -> dict:
or signed DCR identities for core, and remain valid across mode switches.
Public clients use PKCE without a client secret; the registration endpoint
provides the DCR fallback when a client does not use CIMD.

``revocation_endpoint`` is proxy-owned for a second reason (#2248): the
refresh token the client holds is a signed envelope, and core's own
``/auth/revoke`` answers 200 without revoking anything for a value it
cannot recognise. Only ha_auth mints those, so only this document
advertises it. The endpoint takes no client authentication, matching
``token_endpoint_auth_methods_supported``.
"""
return {
"issuer": f"{base}{OAUTH_BASE}",
"authorization_endpoint": f"{base}{OAUTH_BASE}/authorize",
"token_endpoint": f"{base}{OAUTH_BASE}/token",
"registration_endpoint": f"{base}{OAUTH_BASE}/register",
"revocation_endpoint": f"{base}{OAUTH_BASE}/revoke",
"revocation_endpoint_auth_methods_supported": ["none"],
"response_types_supported": ["code"],
"grant_types_supported": ["authorization_code", "refresh_token"],
"code_challenge_methods_supported": ["S256"],
Expand Down
2 changes: 1 addition & 1 deletion homeassistant-addon-webhook-proxy/mcp_proxy/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
"dependencies": ["webhook"],
"documentation": "https://github.com/homeassistant-ai/ha-mcp",
"iot_class": "local_push",
"version": "3.0.1"
"version": "3.0.2"
}
Loading
Loading