Documentation
¶
Overview ¶
Package mcpapi exposes outpost's configuration surface to agent tools (Claude Code, Windsurf, the outpost CLI, ...) over the Model Context Protocol. It is mounted as an http.Handler at /mcp/* on the same loopback listener the admin UI uses (default 127.0.0.1:17777), with a separate bearer-token auth gate so the two surfaces never share credentials.
Every MCP tool registered here is a thin call into internal/agent/admincore — the same business-logic layer the admin UI's HTTP handlers dispatch into. Validation, FileConfig mutation, live AppRegistry / OutboundManager updates, and restart debouncing happen once, regardless of which surface the operator chose.
Auth model: shared bearer token persisted in FileConfig.MCPBearerToken (mode 0600 same as the admin session key). The operator copies the token into their .mcp.json:
{
"outpost": {
"type": "http",
"url": "http://127.0.0.1:17777/mcp/",
"headers": {"Authorization": "Bearer <token>"}
}
}
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Deps ¶
type Deps struct {
Core *admincore.Server
Token string
Version string
RotateFn func() (string, error)
Upgrader *upgrade.Worker
Ledger *upgrade.Ledger
// PeersFn returns the daemon's current discovery cache snapshot
// (typically discovery.Cache.Snapshot()). Nil when discovery is
// off; the outpost://peers resource then returns an empty list.
PeersFn func() any
// GossipMembersFn returns the SWIM gossip member list (roadmap
// item #17). Backs the outpost_gossip_edges MCP tool. Nil when
// gossip is off.
GossipMembersFn func() any
}
Deps is what main.go threads in. Core is the shared admincore.Server instance also given to adminui. Token is the persisted bearer the caller must present; RotateFn is invoked when a tool requests a fresh value (returns the new token; mcpapi swaps s.token before responding).
Upgrader + Ledger are the cloudbox-upgrade surface. Nil on unpaired hosts (and the corresponding tools simply don't register).
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server wraps the modelcontextprotocol/go-sdk MCP server with outpost- specific tool registrations and a static bearer-token auth gate.
func New ¶
New constructs the MCP server and registers every parity tool. Call Handler() to obtain the http.Handler to mount under /mcp/* on the shared listener.
func (*Server) Close ¶
func (s *Server) Close()
Close terminates every open MCP session. Called on daemon shutdown before http.Server.Shutdown so the long-lived SSE streams the streamable transport keeps open don't block listener teardown until the 5-second timeout fires (forcing an SIGKILL fallback in `outpost stop`).
Iterating Server.Sessions() during teardown is safe — no new sessions are created once the listener is shutting down, and the SDK guards the iterator against concurrent modification.
func (*Server) Handler ¶
Handler returns the http.Handler that the shared gin engine mounts at /mcp/*. The bearer-token middleware is already wrapped in.
func (*Server) Rotate ¶
Rotate mints a fresh bearer (via rotateFn — typically conf.RotateMCPBearerToken), swaps s.token atomically, and returns the new value. The OLD token stops authenticating immediately. The admin UI's "Rotate" button and the outpost_rotate_mcp_token MCP tool both end up here so the in-memory state stays consistent regardless of which surface initiates the rotation.