|
| 1 | +# Feature Specification: Unified Health Status |
| 2 | + |
| 3 | +**Feature Branch**: `012-unified-health-status` |
| 4 | +**Created**: 2025-12-11 |
| 5 | +**Status**: Draft |
| 6 | +**Input**: User description: "from docs/designs/2025-12-10-unified-health-status.md" |
| 7 | +**Design Document**: [docs/designs/2025-12-10-unified-health-status.md](../../docs/designs/2025-12-10-unified-health-status.md) |
| 8 | + |
| 9 | +## Problem Statement |
| 10 | + |
| 11 | +MCPProxy currently displays inconsistent server health status across its three interfaces: |
| 12 | + |
| 13 | +1. **CLI** reads `oauth_status` and shows "Token Expired" |
| 14 | +2. **Tray** only checks HTTP connectivity and shows "Healthy" |
| 15 | +3. **Web UI** may show different status based on its own interpretation |
| 16 | + |
| 17 | +This leads to user confusion when the same server shows different states in different interfaces. Additionally, when servers have issues, users often don't know what action to take to resolve them. |
| 18 | + |
| 19 | +## User Scenarios & Testing *(mandatory)* |
| 20 | + |
| 21 | +### User Story 1 - Consistent Status Across Interfaces (Priority: P1) |
| 22 | + |
| 23 | +As a user, I want to see the same health status for a server regardless of whether I'm using the CLI, tray, or web UI, so I can trust the information and not be confused by conflicting reports. |
| 24 | + |
| 25 | +**Why this priority**: This is the core problem - inconsistent status erodes trust and causes confusion. Without this, all other improvements are undermined. |
| 26 | + |
| 27 | +**Independent Test**: Can be tested by checking any server's status in all three interfaces and verifying they show identical health level and summary. |
| 28 | + |
| 29 | +**Acceptance Scenarios**: |
| 30 | + |
| 31 | +1. **Given** a server with an expired OAuth token, **When** I check status in CLI, tray, and web UI, **Then** all three show "unhealthy" status with the same summary message. |
| 32 | +2. **Given** a healthy connected server, **When** I check status in CLI, tray, and web UI, **Then** all three show "healthy" status with matching tool counts. |
| 33 | +3. **Given** a disabled server, **When** I check status in all interfaces, **Then** all three show "disabled" admin state consistently. |
| 34 | + |
| 35 | +--- |
| 36 | + |
| 37 | +### User Story 2 - Actionable Guidance for Issues (Priority: P1) |
| 38 | + |
| 39 | +As a user, when a server has an issue, I want to see what action I should take to fix it, so I don't have to guess or search documentation. |
| 40 | + |
| 41 | +**Why this priority**: Equally critical to consistency - users need to know HOW to fix problems, not just that problems exist. |
| 42 | + |
| 43 | +**Independent Test**: Can be tested by creating various error conditions and verifying each displays an appropriate action. |
| 44 | + |
| 45 | +**Acceptance Scenarios**: |
| 46 | + |
| 47 | +1. **Given** a server with expired OAuth token, **When** I view its status, **Then** I see an action suggesting to login (CLI shows command, tray/web show button). |
| 48 | +2. **Given** a server with connection refused error, **When** I view its status, **Then** I see an action suggesting to restart. |
| 49 | +3. **Given** a healthy server, **When** I view its status, **Then** no action is shown (none needed). |
| 50 | + |
| 51 | +--- |
| 52 | + |
| 53 | +### User Story 3 - OAuth Token Visibility in Tray/Web (Priority: P2) |
| 54 | + |
| 55 | +As a user, I want to see OAuth token issues (expired, expiring soon) in the tray and web UI, not just the CLI, so I'm aware of authentication problems across all interfaces. |
| 56 | + |
| 57 | +**Why this priority**: Addresses a specific gap where OAuth status was only visible in CLI, which many users don't use regularly. |
| 58 | + |
| 59 | +**Independent Test**: Can be tested by letting an OAuth token expire and verifying tray and web UI both indicate the issue. |
| 60 | + |
| 61 | +**Acceptance Scenarios**: |
| 62 | + |
| 63 | +1. **Given** a server with OAuth token expiring in 30 minutes (and no refresh token), **When** I view the tray menu, **Then** I see a yellow/degraded status indicator with "Token expiring" message. |
| 64 | +2. **Given** a server with expired OAuth token, **When** I view the web dashboard, **Then** I see the server listed as needing attention with a Login action. |
| 65 | + |
| 66 | +--- |
| 67 | + |
| 68 | +### User Story 4 - Admin State Separate from Health (Priority: P2) |
| 69 | + |
| 70 | +As a user, I want disabled and quarantined servers to show their admin state clearly distinct from health status, so I understand they're intentionally inactive rather than broken. |
| 71 | + |
| 72 | +**Why this priority**: Prevents confusion between "server is off" and "server is broken". |
| 73 | + |
| 74 | +**Independent Test**: Can be tested by disabling a server and verifying it shows disabled state, not an error. |
| 75 | + |
| 76 | +**Acceptance Scenarios**: |
| 77 | + |
| 78 | +1. **Given** a disabled server, **When** I view its status, **Then** I see "Disabled" admin state (not "unhealthy" or "error"). |
| 79 | +2. **Given** a quarantined server, **When** I view its status, **Then** I see "Quarantined" admin state with an "approve" action. |
| 80 | + |
| 81 | +--- |
| 82 | + |
| 83 | +### User Story 5 - Dashboard Shows Servers Needing Attention (Priority: P3) |
| 84 | + |
| 85 | +As a user, I want the web dashboard to highlight servers that need attention (degraded or unhealthy), so I can quickly identify and fix issues. |
| 86 | + |
| 87 | +**Why this priority**: Quality-of-life improvement that builds on the core health status feature. |
| 88 | + |
| 89 | +**Independent Test**: Can be tested by having a mix of healthy and unhealthy servers and verifying dashboard shows the right count/list. |
| 90 | + |
| 91 | +**Acceptance Scenarios**: |
| 92 | + |
| 93 | +1. **Given** 3 healthy servers and 2 unhealthy servers, **When** I view the dashboard, **Then** I see "2 servers need attention" with quick-fix buttons. |
| 94 | +2. **Given** all servers healthy, **When** I view the dashboard, **Then** I see no "needs attention" banner. |
| 95 | + |
| 96 | +--- |
| 97 | + |
| 98 | +### Edge Cases |
| 99 | + |
| 100 | +- What happens when a server is both disabled AND has an expired token? Admin state takes precedence - show "Disabled". |
| 101 | +- How does system handle servers that are connecting but not yet ready? Show "degraded" with no action required. |
| 102 | +- What if OAuth auto-refresh is working but token is about to expire? Show "healthy" - auto-refresh handles it automatically. |
| 103 | +- What if token has no expiration time set? Assume valid if no explicit expiration. |
| 104 | + |
| 105 | +## Requirements *(mandatory)* |
| 106 | + |
| 107 | +### Functional Requirements |
| 108 | + |
| 109 | +- **FR-001**: System MUST calculate a single unified health status in the backend for each server |
| 110 | +- **FR-002**: System MUST include health level (healthy/degraded/unhealthy) in the status |
| 111 | +- **FR-003**: System MUST include admin state (enabled/disabled/quarantined) separate from health |
| 112 | +- **FR-004**: System MUST include a human-readable summary message in the status |
| 113 | +- **FR-005**: System MUST include an action type (login/restart/enable/approve/view_logs) when applicable |
| 114 | +- **FR-006**: CLI MUST display health status with appropriate emoji indicators |
| 115 | +- **FR-007**: CLI MUST display action as a command hint (e.g., "auth login --server=X") |
| 116 | +- **FR-008**: Tray MUST display health status with consistent emoji indicators matching CLI |
| 117 | +- **FR-009**: Tray MUST provide clickable actions that resolve the issue (open web UI or trigger API) |
| 118 | +- **FR-010**: Web UI MUST display health status with colored badges |
| 119 | +- **FR-011**: Web UI MUST display action buttons appropriate to each issue type |
| 120 | +- **FR-012**: Dashboard MUST show count of servers needing attention |
| 121 | +- **FR-013**: Admin state MUST take precedence over health when server is not enabled |
| 122 | +- **FR-014**: OAuth token expiration MUST be considered unhealthy (not degraded) |
| 123 | +- **FR-015**: OAuth token expiring soon with no refresh token MUST be considered degraded |
| 124 | +- **FR-016**: OAuth token with working auto-refresh MUST be considered healthy regardless of expiration time |
| 125 | + |
| 126 | +### Key Entities |
| 127 | + |
| 128 | +- **HealthStatus**: Represents the unified health of a server |
| 129 | + - Level: healthy, degraded, or unhealthy |
| 130 | + - AdminState: enabled, disabled, or quarantined |
| 131 | + - Summary: Human-readable status message |
| 132 | + - Detail: Optional longer explanation |
| 133 | + - Action: Suggested fix action type |
| 134 | + |
| 135 | +- **Server**: Existing entity extended with Health field |
| 136 | + - All existing fields preserved |
| 137 | + - New Health field containing HealthStatus |
| 138 | + |
| 139 | +## Success Criteria *(mandatory)* |
| 140 | + |
| 141 | +### Measurable Outcomes |
| 142 | + |
| 143 | +- **SC-001**: All three interfaces (CLI, tray, web) display identical health level for any given server |
| 144 | +- **SC-002**: 100% of unhealthy/degraded states include an appropriate action suggestion |
| 145 | +- **SC-003**: Users can identify and fix server issues without consulting documentation |
| 146 | +- **SC-004**: OAuth token expiration is visible in tray and web UI (not just CLI) |
| 147 | +- **SC-005**: Admin state (disabled/quarantined) is visually distinct from health issues in all interfaces |
| 148 | + |
| 149 | +## Assumptions |
| 150 | + |
| 151 | +- All clients (CLI, tray, web) are deployed together, so no backward compatibility is needed |
| 152 | +- The existing `/api/v1/servers` endpoint will be extended to include the health field |
| 153 | +- Token expiration threshold for "expiring soon" warning is configurable (default: 1 hour) |
| 154 | +- Auto-refresh working means the system will handle token renewal automatically |
| 155 | + |
| 156 | +## Commit Message Conventions *(mandatory)* |
| 157 | + |
| 158 | +When committing changes for this feature, follow these guidelines: |
| 159 | + |
| 160 | +### Issue References |
| 161 | +- Use: `Related #[issue-number]` - Links the commit to the issue without auto-closing |
| 162 | +- Do NOT use: `Fixes #[issue-number]`, `Closes #[issue-number]`, `Resolves #[issue-number]` - These auto-close issues on merge |
| 163 | + |
| 164 | +**Rationale**: Issues should only be closed manually after verification and testing in production, not automatically on merge. |
| 165 | + |
| 166 | +### Co-Authorship |
| 167 | +- Do NOT include: `Co-Authored-By: Claude <noreply@anthropic.com>` |
| 168 | +- Do NOT include: "Generated with Claude Code" |
| 169 | + |
| 170 | +**Rationale**: Commit authorship should reflect the human contributors, not the AI tools used. |
0 commit comments