docs/shared-management-health-plan.md
Goal: converge upstream management and diagnostics so CLI, REST, and MCP tools all call the same code paths, honoring config gates (disable_management, read_only) and producing consistent outputs.
Create internal/management/service.go (or internal/runtime/management/service.go):
type ManagementService interface {
ListServers(ctx context.Context) ([]*contracts.Server, *contracts.ServerStats, error)
GetServerLogs(ctx context.Context, name string, tail int) ([]contracts.LogEntry, error)
Enable(ctx context.Context, name string) error
Disable(ctx context.Context, name string) error
Restart(ctx context.Context, name string) error
RestartAll(ctx context.Context) error
EnableAll(ctx context.Context) (int, error) // returns count
DisableAll(ctx context.Context) (int, error)
Doctor(ctx context.Context) (*contracts.Diagnostics, error)
AuthStatus(ctx context.Context, name string) (*contracts.AuthStatus, error)
AuthLogin(ctx context.Context, name string) error
}
Implementation wires into existing upstream manager (internal/server/manager.go), log reader, secret resolver, OAuth helpers, and Docker recovery state.
GET /api/v1/servers → ListServersGET /api/v1/servers/{id}/logs → GetServerLogsPOST /api/v1/servers/{id}/enable|disable|restart → respective service callsPOST /api/v1/servers/restart_all|enable_all|disable_all → bulk helpersGET /api/v1/doctor → DoctorGET /api/v1/servers/{id}/auth and POST /api/v1/servers/{id}/login → AuthStatus/AuthLogincontracts.Diagnostics if missing.upstream_servers handler should delegate to the service for list/log/toggle/restart (add a restart op).doctor MCP tool that returns the same diagnostics structure as REST/CLI.cmd/mcpproxy/upstream_cmd.go: in daemon mode, continue using internal/cliclient, but have cliclient hit the new REST endpoints; standalone fallback can call the service directly (optional).cmd/mcpproxy/doctor_cmd.go: call Doctor via REST client; output JSON/pretty using the shared schema.internal/cliclient/client.go: add methods for Doctor, bulk actions, and restart with the new endpoints.read_only and disable_management checks inside the service; REST/MCP/CLI do not re-implement guards.--all versus named server inside CLI before hitting the service (already done for flags), and service should still block disallowed operations.contracts types: Server, ServerStats, LogEntry.contracts.Diagnostics with fields already used in doctor command: total_issues, upstream_errors, oauth_required, missing_secrets, runtime_warnings, docker_status.contracts.AuthStatus if not present (fields: server, state, expires_at, message).internal/management/service.go (+ tests).internal/server/manager.go (expose methods the service uses), internal/httpapi/server.go (route endpoints to service), internal/server/mcp.go (delegate tool handlers), internal/cliclient/client.go (new methods/endpoints), cmd/mcpproxy/upstream_cmd.go and cmd/mcpproxy/doctor_cmd.go (no logic changes; rely on REST updates).internal/contracts/*.go add diagnostics/auth structs if missing.ManagementService interface and concrete implementation backed by existing runtime/manager/logs/diagnostics code.contracts; ensure doctor uses it end-to-end.upstream_servers, new doctor, optional auth tool).internal/cliclient with new endpoints and update CLI commands to consume them (minimal CLI code churn).docs/cli-management-commands.md and CLAUDE.md with the surface mapping (CLI ↔ REST ↔ MCP).