Documentation
¶
Overview ¶
Package adminui serves the local-only configuration web UI for outpost.
The server binds its own loopback listener (default 127.0.0.1:17777, override via $OUTPOST_ADMIN_ADDR). It is intentionally not part of the main HTTP server that the matrix tunnel proxies — admin is local-only by design.
On first run (no config file on disk yet) the admin API is unauthenticated: the listener is loopback-only, so any reachable caller is the OS user who just launched the binary. Once a config exists the gate engages and every API call must carry an outpost_admin session cookie minted by POST /api/login (which verifies the running OS user's password via hostauth).
Business-logic operations (validate / mutate FileConfig / mutate live registries / debounce restart) live in internal/agent/admincore so the MCP server can share them. This package is now a thin HTTP layer: session-cookie auth, JSON binding, error→status mapping.
Index ¶
Constants ¶
const DefaultAdminAddr = "127.0.0.1:17777"
DefaultAdminAddr is the loopback listener address the admin UI binds when neither $OUTPOST_ADMIN_ADDR nor --admin-addr is set.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Deps ¶
type Deps struct {
// Core, when non-nil, is the shared admincore.Server that mutation
// handlers dispatch into. When nil, New() builds one from the
// legacy fields below — the test path.
Core *admincore.Server
// ListenAddr is the loopback address+port the admin server binds.
// Defaults to 127.0.0.1:17777 if empty.
ListenAddr string
// Auth verifies the running OS user's password on POST /api/login.
Auth hostauth.Authenticator
// SessionKey is the HMAC secret used to sign admin-UI session
// cookies. Persisting it across restarts is what keeps the admin
// logged in when a built-in toggle re-execs the binary.
SessionKey []byte
// MCPEndpoint is the URL the operator pastes into .mcp.json. Set
// by main.go after constructing mcpapi. Empty when the MCP server
// isn't wired (test paths).
MCPEndpoint string
// MCPToken returns the currently-accepted bearer (mcpapi rotates
// it in memory; this closure always reads the live value).
MCPToken func() string
// RotateMCPToken mints a fresh token, persists it, swaps mcpapi's
// in-memory copy, and returns the new value.
RotateMCPToken func() (string, error)
// OnShutdown, when set, is called once on context cancel right
// before http.Server.Shutdown begins. Used by main.go to close
// long-lived MCP SSE sessions so Shutdown doesn't have to wait
// for them to drain (which would otherwise force `outpost stop`
// into its SIGKILL fallback after 5 seconds). Synchronous; runs
// in the Serve goroutine, so keep it bounded.
OnShutdown func()
ConfigPath string
Apps *agent.AppRegistry
Outbound *agent.OutboundManager
Restart func()
CloudboxBase string
CloudboxAccessToken string
AgentName string
LLMPoolStatus func() LLMPoolStatusView
}
Deps is what main.go threads in when constructing the admin server.
Two construction modes:
Production (main.go): supply Core, plus the HTTP-only fields (ListenAddr, Auth, SessionKey). The admincore.Server is shared with mcpapi so both surfaces see the same live state, the same file-save mutex, and the same restart-debounce timer.
Test convenience: leave Core nil and supply the legacy fields (ConfigPath, Apps, Outbound, ...). New() then constructs an admincore.Server internally.
type LLMPoolStatusView ¶
type LLMPoolStatusView = admincore.LLMPoolStatusView
LLMPoolStatusView is re-exported from admincore so existing callers (main.go, tests) keep working without an import shuffle.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is the admin HTTP server. Construct with New, then call Serve.
func New ¶
New builds the admin server and binds its listener. The returned Server is not yet serving — call Serve.
func (*Server) Engine ¶
Engine returns the underlying gin engine. mcpapi mounts its handler at /mcp/* here so MCP and admin UI share one loopback listener (one URL the operator copy-pastes, one port the firewall sees). The bearer-token middleware lives inside mcpapi — adminui doesn't see /mcp/* traffic; the route is registered after adminui's own routes, so admin's session-cookie middleware never inspects it.
func (*Server) SetMCPEndpoint ¶
SetMCPEndpoint backfills the URL the SPA's "Show .mcp.json snippet" panel renders. main.go calls this after the listener is bound (the URL isn't known earlier because :0 may resolve to a random port).
type Suggestion ¶
type Suggestion = admincore.Suggestion
Suggestion is re-exported from admincore for backward compat with tests that reference the name unqualified.