Commit cc708f0
fix: HA Core proxy fallback for ha_get_logs(source=system_service) on non-addon installs (#1283)
* fix: HA Core proxy fallback for ha_get_logs(source=system_service) on non-addon installs
Closes #1260. Pre-fix `_get_system_service_logs` had only the Supervisor-direct
branch, so non-addon installs (the Docker image, uvx ha-mcp, pip-based deploys)
fell straight through to the SUPERVISOR_TOKEN-absent fail-fast in
`_supervisor_logs_get` for every system-service slug. Sibling `get_addon_logs`
and `get_error_log` already had the `is_running_in_addon()` gate plus HA Core
proxy fallback added in PR #1126; this PR closes the parallel gap.
The reproduced symptom matched the issue exactly on a non-addon install
(uvx ha-mcp pointed at a Supervisor-equipped HA): `source="supervisor"` worked
via the existing Core proxy fallback, while `source="system_service"` with
slug in {supervisor, host, core} returned AUTH_INVALID_TOKEN with the
misleading "addon-mode gate fired but SUPERVISOR_TOKEN env var not set"
message. Once the gate is added, that fail-fast string is accurate again
because the only callers reaching it are addon-mode-confirmed.
Verified the proxy path is reachable for all seven service slugs by reading
HA Core's `homeassistant/components/hassio/http.py` — PATHS_ADMIN whitelists
`{audio,cli,core,dns,host,multicast,observer,supervisor}/logs` plus
`addons/{slug}/logs`. Admin LLA is sufficient. (HA Core also proxies
`cli/logs`, which ha-mcp's SYSTEM_SERVICE_SLUGS doesn't include — leaving
that out as scope for a separate PR if anyone wants CLI logs surfaced.)
Tests: new TestGetSystemServiceLogsBranchSelection class mirrors the
existing TestGetAddonLogsBranchSelection / TestGetErrorLogBranchSelection
shape — non-addon branch parametrized over all seven slugs, plus an
addon-branch test that proxy is not called.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test(rest_client): Accept header + 404 path on system_service non-addon branch
Two parity additions in TestGetSystemServiceLogsBranchSelection, per PR
review by pr-test-analyzer:
- Parametrized happy-path test now asserts `Accept: text/plain` on the
proxy request. Without it the HA Core proxy negotiates application/json
and the body stops being raw log text (same silent-failure signature
#950 describes one layer up).
- New `test_non_addon_install_404_raises_api_error_with_service_context`
anchors the live "observer returned 404 on hubs that don't run it"
case from the #1260 end-to-end verification. Guards against a future
refactor wrapping the proxy call in a swallow-and-return-empty
try/except in `_get_system_service_logs`. Parallels
`TestGetAddonLogs::test_raises_api_error_on_404_with_slug_context`.
64 tests pass in this file (was 63), ruff clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(get_logs): branch-aware error suggestions + add cli to system_service slugs
Two follow-ons from the PR #1283 review, both addressing review findings
that were initially deferred as "future improvements" but are real
behavior issues introduced or exposed by this PR's branch split:
1. Branch-aware wrapper suggestions in tools_utility.py:
Pre-fix, the AuthError and 403 branches in `_get_supervisor_log` and
`_get_system_service_log` always emitted SUPERVISOR_TOKEN/hassio_role
hints — useless on non-addon installs that hit the new HA Core proxy
path. With #1283's gate-and-fallback split, the wrapper now gates on
`is_running_in_addon()` and picks branch-appropriate suggestions:
- In-addon AuthError → "Verify SUPERVISOR_TOKEN..." (unchanged)
- Non-addon AuthError → "Verify HOMEASSISTANT_TOKEN is a valid admin
Long-Lived Access Token..."
- In-addon 403 (system_service) → "Addon's hassio_role must be
'manager'..." (unchanged)
- Non-addon 403 (system_service) → "The LLA must belong to an admin..."
Same shape applied to `_get_supervisor_log` so source="supervisor"
doesn't have the same dead-end advice on Docker/uvx installs either.
2. Add `cli` to SYSTEM_SERVICE_SLUGS:
HA Core's hassio HTTP proxy already whitelists `cli/logs` in
PATHS_ADMIN. Adding the slug surfaces Supervisor CLI logs via the
same routes #1116 set up for the other seven services. Eight slugs
total now.
Tests:
- Parametrized non-addon proxy test extended to 8 slugs (cli added)
- `test_all_seven_allowed_services_dispatch` renamed → `_all_allowed_`,
extended to 8 slugs
- Existing `test_403_role_hint_suggestion` renamed to clarify it's the
in-addon case + explicit `is_running_in_addon` mock added
- 5 new tests pinning the branch-aware suggestion behavior (in-addon
AuthError, non-addon AuthError, non-addon 403) on both wrappers
- Supervisor mock updated to recognize the 8-slug set
- Backtick consistency in TestGetAddonLogsBranchSelection +
TestGetSystemServiceLogsBranchSelection class docstrings, per
comment-analyzer S3
71 unit tests pass in test_tools_utility_supervisor_logs.py (was 63 pre-PR,
64 after first review-pass test additions). Ruff clean across all
touched files.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: kingpanther13 <kingpanther13@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 4c44ba4 commit cc708f0
4 files changed
Lines changed: 380 additions & 54 deletions
File tree
- src/ha_mcp
- client
- tools
- tests/src
- e2e/utilities
- unit
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
527 | 527 | | |
528 | 528 | | |
529 | 529 | | |
530 | | - | |
| 530 | + | |
531 | 531 | | |
532 | 532 | | |
533 | 533 | | |
| |||
645 | 645 | | |
646 | 646 | | |
647 | 647 | | |
648 | | - | |
649 | | - | |
650 | | - | |
651 | | - | |
652 | | - | |
653 | | - | |
654 | | - | |
655 | | - | |
656 | | - | |
657 | | - | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
658 | 673 | | |
659 | | - | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
660 | 684 | | |
661 | 685 | | |
662 | 686 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| 15 | + | |
15 | 16 | | |
16 | 17 | | |
17 | 18 | | |
| |||
42 | 43 | | |
43 | 44 | | |
44 | 45 | | |
45 | | - | |
46 | | - | |
47 | | - | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
48 | 50 | | |
49 | | - | |
| 51 | + | |
50 | 52 | | |
51 | 53 | | |
52 | 54 | | |
| |||
145 | 147 | | |
146 | 148 | | |
147 | 149 | | |
148 | | - | |
| 150 | + | |
149 | 151 | | |
150 | 152 | | |
151 | 153 | | |
| |||
762 | 764 | | |
763 | 765 | | |
764 | 766 | | |
765 | | - | |
766 | | - | |
| 767 | + | |
| 768 | + | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
767 | 786 | | |
768 | 787 | | |
769 | 788 | | |
770 | | - | |
771 | | - | |
772 | | - | |
773 | | - | |
| 789 | + | |
774 | 790 | | |
775 | 791 | | |
776 | 792 | | |
| |||
832 | 848 | | |
833 | 849 | | |
834 | 850 | | |
835 | | - | |
| 851 | + | |
| 852 | + | |
836 | 853 | | |
837 | | - | |
838 | | - | |
839 | | - | |
840 | | - | |
841 | | - | |
| 854 | + | |
| 855 | + | |
| 856 | + | |
| 857 | + | |
| 858 | + | |
| 859 | + | |
842 | 860 | | |
843 | 861 | | |
844 | 862 | | |
| |||
877 | 895 | | |
878 | 896 | | |
879 | 897 | | |
880 | | - | |
881 | | - | |
| 898 | + | |
| 899 | + | |
| 900 | + | |
| 901 | + | |
| 902 | + | |
| 903 | + | |
| 904 | + | |
| 905 | + | |
| 906 | + | |
| 907 | + | |
| 908 | + | |
| 909 | + | |
| 910 | + | |
| 911 | + | |
| 912 | + | |
| 913 | + | |
| 914 | + | |
882 | 915 | | |
883 | 916 | | |
884 | 917 | | |
885 | | - | |
886 | | - | |
887 | | - | |
888 | | - | |
| 918 | + | |
889 | 919 | | |
890 | 920 | | |
891 | 921 | | |
892 | 922 | | |
893 | | - | |
894 | | - | |
895 | | - | |
896 | | - | |
897 | | - | |
| 923 | + | |
| 924 | + | |
| 925 | + | |
| 926 | + | |
| 927 | + | |
| 928 | + | |
898 | 929 | | |
899 | 930 | | |
900 | 931 | | |
901 | 932 | | |
902 | | - | |
| 933 | + | |
| 934 | + | |
| 935 | + | |
| 936 | + | |
| 937 | + | |
| 938 | + | |
| 939 | + | |
| 940 | + | |
| 941 | + | |
| 942 | + | |
| 943 | + | |
| 944 | + | |
903 | 945 | | |
904 | 946 | | |
905 | 947 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
23 | | - | |
| 23 | + | |
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
50 | | - | |
| 50 | + | |
51 | 51 | | |
52 | 52 | | |
53 | | - | |
| 53 | + | |
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
| |||
0 commit comments