diff --git a/cmd/mcpproxy/status_cmd.go b/cmd/mcpproxy/status_cmd.go index 9cde5374..8448d283 100644 --- a/cmd/mcpproxy/status_cmd.go +++ b/cmd/mcpproxy/status_cmd.go @@ -21,16 +21,24 @@ import ( // StatusInfo holds the collected status data for display. type StatusInfo struct { - State string `json:"state"` - ListenAddr string `json:"listen_addr"` - Uptime string `json:"uptime,omitempty"` - UptimeSeconds float64 `json:"uptime_seconds,omitempty"` - APIKey string `json:"api_key"` - WebUIURL string `json:"web_ui_url"` - Servers *ServerCounts `json:"servers,omitempty"` - SocketPath string `json:"socket_path,omitempty"` - ConfigPath string `json:"config_path,omitempty"` - Version string `json:"version,omitempty"` + State string `json:"state"` + Edition string `json:"edition"` + ListenAddr string `json:"listen_addr"` + Uptime string `json:"uptime,omitempty"` + UptimeSeconds float64 `json:"uptime_seconds,omitempty"` + APIKey string `json:"api_key"` + WebUIURL string `json:"web_ui_url"` + Servers *ServerCounts `json:"servers,omitempty"` + SocketPath string `json:"socket_path,omitempty"` + ConfigPath string `json:"config_path,omitempty"` + Version string `json:"version,omitempty"` + TeamsInfo *TeamsStatusInfo `json:"teams,omitempty"` +} + +// TeamsStatusInfo holds teams-specific status information. +type TeamsStatusInfo struct { + OAuthProvider string `json:"oauth_provider"` + AdminEmails []string `json:"admin_emails"` } // ServerCounts holds upstream server statistics. @@ -151,11 +159,15 @@ func collectStatusFromDaemon(cfg *config.Config, socketPath, configPath string) info := &StatusInfo{ State: "Running", + Edition: Edition, APIKey: cfg.APIKey, SocketPath: socketPath, ConfigPath: configPath, } + // Add teams info if available + info.TeamsInfo = collectTeamsInfo(cfg) + // Get status data (running, listen_addr, upstream_stats) statusData, err := client.GetStatus(ctx) if err != nil { @@ -208,13 +220,18 @@ func collectStatusFromConfig(cfg *config.Config, socketPath, configPath string) listenAddr = "127.0.0.1:8080" } - return &StatusInfo{ + info := &StatusInfo{ State: "Not running", + Edition: Edition, ListenAddr: listenAddr + " (configured)", APIKey: cfg.APIKey, WebUIURL: statusBuildWebUIURL(listenAddr, cfg.APIKey), ConfigPath: configPath, } + + info.TeamsInfo = collectTeamsInfo(cfg) + + return info } func extractServerCounts(stats map[string]interface{}) *ServerCounts { @@ -321,6 +338,7 @@ func printStatusTable(info *StatusInfo) { fmt.Println("MCPProxy Status") fmt.Printf(" %-12s %s\n", "State:", info.State) + fmt.Printf(" %-12s %s\n", "Edition:", info.Edition) if info.Version != "" { fmt.Printf(" %-12s %s\n", "Version:", info.Version) @@ -346,6 +364,13 @@ func printStatusTable(info *StatusInfo) { if info.ConfigPath != "" { fmt.Printf(" %-12s %s\n", "Config:", info.ConfigPath) } + + if info.TeamsInfo != nil { + fmt.Println() + fmt.Println("Teams") + fmt.Printf(" %-12s %s\n", "OAuth:", info.TeamsInfo.OAuthProvider) + fmt.Printf(" %-12s %s\n", "Admins:", strings.Join(info.TeamsInfo.AdminEmails, ", ")) + } } func loadStatusConfig() (*config.Config, error) { diff --git a/cmd/mcpproxy/status_teams.go b/cmd/mcpproxy/status_teams.go new file mode 100644 index 00000000..f77755ce --- /dev/null +++ b/cmd/mcpproxy/status_teams.go @@ -0,0 +1,18 @@ +//go:build teams + +package main + +import "github.com/smart-mcp-proxy/mcpproxy-go/internal/config" + +func collectTeamsInfo(cfg *config.Config) *TeamsStatusInfo { + if cfg.Teams == nil || !cfg.Teams.Enabled { + return nil + } + info := &TeamsStatusInfo{ + AdminEmails: cfg.Teams.AdminEmails, + } + if cfg.Teams.OAuth != nil { + info.OAuthProvider = cfg.Teams.OAuth.Provider + } + return info +} diff --git a/cmd/mcpproxy/status_teams_stub.go b/cmd/mcpproxy/status_teams_stub.go new file mode 100644 index 00000000..327de7e7 --- /dev/null +++ b/cmd/mcpproxy/status_teams_stub.go @@ -0,0 +1,9 @@ +//go:build !teams + +package main + +import "github.com/smart-mcp-proxy/mcpproxy-go/internal/config" + +func collectTeamsInfo(_ *config.Config) *TeamsStatusInfo { + return nil +} diff --git a/cmd/mcpproxy/teams_register.go b/cmd/mcpproxy/teams_register.go index b464b418..d2647b0d 100644 --- a/cmd/mcpproxy/teams_register.go +++ b/cmd/mcpproxy/teams_register.go @@ -2,17 +2,10 @@ package main -import ( - "log" - - "github.com/smart-mcp-proxy/mcpproxy-go/internal/teams" -) - -func init() { - // Initialize all registered teams features. - // Individual feature packages (auth, workspace, etc.) register - // themselves via their own init() functions. - if err := teams.SetupAll(teams.Dependencies{}); err != nil { - log.Fatalf("failed to initialize teams features: %v", err) - } -} +// Teams features are registered via init() functions in their respective +// packages. The actual setup happens when the server calls teams.SetupAll() +// during HTTP server initialization (see internal/server/teams_wire.go). +// +// This file imports the teams package for its init() side effects, +// which register feature modules in the teams registry. +import _ "github.com/smart-mcp-proxy/mcpproxy-go/internal/teams" diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 7b3e907a..babaa029 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -47,10 +47,12 @@ import ConnectionStatus from '@/components/ConnectionStatus.vue' import AuthErrorModal from '@/components/AuthErrorModal.vue' import { useSystemStore } from '@/stores/system' import { useServersStore } from '@/stores/servers' +import { useAuthStore } from '@/stores/auth' import api, { type APIAuthEvent } from '@/services/api' const systemStore = useSystemStore() const serversStore = useServersStore() +const authStore = useAuthStore() // Authentication modal state const authModal = reactive({ @@ -93,7 +95,10 @@ function handleAuthError(event: APIAuthEvent) { authModal.show = true } -onMounted(() => { +onMounted(async () => { + // Initialize auth state (needed for teams edition role-based nav) + await authStore.checkAuth() + // Set up API error listener removeAPIListener = api.addEventListener(handleAuthError) @@ -133,4 +138,4 @@ onUnmounted(() => { opacity: 0; transform: translateX(-10px); } - \ No newline at end of file + diff --git a/frontend/src/components/SidebarNav.vue b/frontend/src/components/SidebarNav.vue index bf899c4d..ddc6db76 100644 --- a/frontend/src/components/SidebarNav.vue +++ b/frontend/src/components/SidebarNav.vue @@ -6,25 +6,90 @@
MCPProxy Logo - MCPProxy +
+ MCPProxy + Teams +
-