Documentation
¶
Overview ¶
Package mcpgateway aggregates upstream MCP servers behind GoModel's authenticated /mcp endpoints. The gateway terminates the MCP protocol on both legs: it is an MCP server to clients and an MCP client to upstreams. It is also the credential boundary — client bearer tokens never reach an upstream; upstream credentials come only from server configuration.
Index ¶
- Constants
- Variables
- func NamespacedName(server, name string) string
- type CatalogFeature
- type CatalogResource
- type CatalogTemplate
- type CatalogView
- type ManagedServer
- type Manager
- func (m *Manager) Apply(specs []ServerSpec)
- func (m *Manager) CallTool(ctx context.Context, server, tool string, args json.RawMessage) (*mcp.CallToolResult, error)
- func (m *Manager) Close()
- func (m *Manager) GetPrompt(ctx context.Context, server string, params *mcp.GetPromptParams) (*mcp.GetPromptResult, error)
- func (m *Manager) ReadResource(ctx context.Context, server string, params *mcp.ReadResourceParams) (*mcp.ReadResourceResult, error)
- func (m *Manager) Reconnect(ctx context.Context, name string) (ServerView, error)
- func (m *Manager) Views() []ServerView
- type MongoDBStore
- func (s *MongoDBStore) Close() error
- func (s *MongoDBStore) Delete(ctx context.Context, name string) error
- func (s *MongoDBStore) Get(ctx context.Context, name string) (*ManagedServer, error)
- func (s *MongoDBStore) List(ctx context.Context) ([]ManagedServer, error)
- func (s *MongoDBStore) Upsert(ctx context.Context, server ManagedServer) error
- type Options
- type PostgreSQLStore
- func (s *PostgreSQLStore) Close() error
- func (s *PostgreSQLStore) Delete(ctx context.Context, name string) error
- func (s *PostgreSQLStore) Get(ctx context.Context, name string) (*ManagedServer, error)
- func (s *PostgreSQLStore) List(ctx context.Context) ([]ManagedServer, error)
- func (s *PostgreSQLStore) Upsert(ctx context.Context, server ManagedServer) error
- type Result
- type SQLiteStore
- func (s *SQLiteStore) Close() error
- func (s *SQLiteStore) Delete(ctx context.Context, name string) error
- func (s *SQLiteStore) Get(ctx context.Context, name string) (*ManagedServer, error)
- func (s *SQLiteStore) List(ctx context.Context) ([]ManagedServer, error)
- func (s *SQLiteStore) Upsert(ctx context.Context, server ManagedServer) error
- type ServerSpec
- type ServerStatus
- type ServerView
- type Service
- func (s *Service) Catalog(name string) (CatalogView, bool)
- func (s *Service) Close()
- func (s *Service) Delete(ctx context.Context, name string) error
- func (s *Service) GetManaged(ctx context.Context, name string) (*ManagedServer, error)
- func (s *Service) IsManaged(name string) bool
- func (s *Service) Reconnect(ctx context.Context, name string) (ServerView, error)
- func (s *Service) Reload(ctx context.Context) error
- func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request, pinnedServer string) error
- func (s *Service) Upsert(ctx context.Context, server ManagedServer) error
- func (s *Service) Views() []ServerView
- type Store
Constants ¶
const ScopeHeader = "X-MCP-Servers"
ScopeHeader restricts a request's visible servers to a comma-separated subset, so one gateway key can serve differently-scoped clients without extra endpoints. Unknown names are ignored; an empty header means all.
Variables ¶
var ErrNotFound = errors.New("mcp server not found")
ErrNotFound indicates a requested managed MCP server was not found.
Functions ¶
func NamespacedName ¶
NamespacedName is the aggregated-endpoint name for one upstream feature.
Types ¶
type CatalogFeature ¶
type CatalogFeature struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
}
CatalogFeature is one listed tool or prompt in a catalog view, using the upstream's original (un-prefixed) name.
type CatalogResource ¶
type CatalogResource struct {
URI string `json:"uri"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
}
CatalogResource is one listed resource in a catalog view.
type CatalogTemplate ¶
type CatalogTemplate struct {
URITemplate string `json:"uri_template"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
}
CatalogTemplate is one listed resource template in a catalog view.
type CatalogView ¶
type CatalogView struct {
Server string `json:"server"`
Status ServerStatus `json:"status"`
Instructions string `json:"instructions,omitempty"`
Tools []CatalogFeature `json:"tools"`
Prompts []CatalogFeature `json:"prompts"`
Resources []CatalogResource `json:"resources"`
Templates []CatalogTemplate `json:"templates"`
}
CatalogView is the admin-facing snapshot of what one upstream currently exposes through the gateway, after the operator tool filters were applied.
type ManagedServer ¶
type ManagedServer struct {
// Name is the immutable ASCII slug and remains the storage primary key.
Name string `json:"slug"`
DisplayName string `json:"name"`
URL string `json:"url"`
Transport string `json:"transport"`
Headers map[string]string `json:"headers,omitempty"`
Description string `json:"description,omitempty"`
Enabled bool `json:"enabled"`
AllowedTools []string `json:"allowed_tools,omitempty"`
DisallowedTools []string `json:"disallowed_tools,omitempty"`
UserPaths []string `json:"user_paths,omitempty"`
ToolTimeoutSeconds int `json:"tool_timeout_seconds,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
ManagedServer is one admin-managed upstream server row. Stdio fields are deliberately absent: runtime-registered subprocesses are a remote code execution vector (see the gateway spec), so stdio servers exist only as declarative config.
func (ManagedServer) Spec ¶
func (m ManagedServer) Spec() ServerSpec
Spec converts the row into a runtime spec.
func (*ManagedServer) Validate ¶
func (m *ManagedServer) Validate() error
Validate checks the row against the same rules as declarative config, additionally rejecting the stdio transport. The receiver is only mutated (normalized transport/URL) once every check has passed.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager owns the set of upstream connections and their catalogs.
func NewManager ¶
NewManager creates an empty manager. Apply installs the initial specs.
func (*Manager) Apply ¶
func (m *Manager) Apply(specs []ServerSpec)
Apply reconciles the running upstreams with the desired specs: removed servers are closed, new servers are added, changed servers are redialed. Unchanged servers keep their live session and catalog. Initial connects run asynchronously so startup and admin edits never block on upstream IO.
func (*Manager) CallTool ¶
func (m *Manager) CallTool(ctx context.Context, server, tool string, args json.RawMessage) (*mcp.CallToolResult, error)
CallTool forwards one tool call to the named server using the original (un-prefixed) tool name.
func (*Manager) Close ¶
func (m *Manager) Close()
Close terminates the maintenance loop and every upstream session.
func (*Manager) GetPrompt ¶
func (m *Manager) GetPrompt(ctx context.Context, server string, params *mcp.GetPromptParams) (*mcp.GetPromptResult, error)
GetPrompt forwards one prompts/get to the named server.
func (*Manager) ReadResource ¶
func (m *Manager) ReadResource(ctx context.Context, server string, params *mcp.ReadResourceParams) (*mcp.ReadResourceResult, error)
ReadResource forwards one resources/read to the named server.
func (*Manager) Reconnect ¶
Reconnect force-redials one server and relists its catalog synchronously.
func (*Manager) Views ¶
func (m *Manager) Views() []ServerView
Views returns admin snapshots of every upstream, sorted by name.
type MongoDBStore ¶
type MongoDBStore struct {
// contains filtered or unexported fields
}
MongoDBStore stores managed MCP servers in MongoDB.
func NewMongoDBStore ¶
func NewMongoDBStore(database *mongo.Database) (*MongoDBStore, error)
NewMongoDBStore creates collection indexes if needed.
func (*MongoDBStore) Close ¶
func (s *MongoDBStore) Close() error
func (*MongoDBStore) Get ¶
func (s *MongoDBStore) Get(ctx context.Context, name string) (*ManagedServer, error)
func (*MongoDBStore) List ¶
func (s *MongoDBStore) List(ctx context.Context) ([]ManagedServer, error)
func (*MongoDBStore) Upsert ¶
func (s *MongoDBStore) Upsert(ctx context.Context, server ManagedServer) error
type Options ¶
type Options struct {
// ConfigServers are the declarative servers from config.yaml / MCP_SERVERS.
ConfigServers map[string]ServerSpec
// Store persists admin-managed servers. Optional.
Store Store
// HTTPClient is the shared outbound HTTP client for http/sse upstreams.
HTTPClient *http.Client
// UsageLogger records one usage entry per tool call. Optional.
UsageLogger usage.LoggerInterface
// UserPathHeader is the configured user-path header name.
UserPathHeader string
}
Options configures NewService.
type PostgreSQLStore ¶
type PostgreSQLStore struct {
// contains filtered or unexported fields
}
PostgreSQLStore stores managed MCP servers in PostgreSQL.
func NewPostgreSQLStore ¶
NewPostgreSQLStore creates the mcp_servers table and indexes if needed.
func (*PostgreSQLStore) Close ¶
func (s *PostgreSQLStore) Close() error
func (*PostgreSQLStore) Delete ¶
func (s *PostgreSQLStore) Delete(ctx context.Context, name string) error
func (*PostgreSQLStore) Get ¶
func (s *PostgreSQLStore) Get(ctx context.Context, name string) (*ManagedServer, error)
func (*PostgreSQLStore) List ¶
func (s *PostgreSQLStore) List(ctx context.Context) ([]ManagedServer, error)
func (*PostgreSQLStore) Upsert ¶
func (s *PostgreSQLStore) Upsert(ctx context.Context, server ManagedServer) error
type Result ¶
type Result struct {
Service *Service
Store Store
Storage storage.Storage
// contains filtered or unexported fields
}
Result holds the initialized MCP gateway and any owned resources.
func New ¶
func New(ctx context.Context, cfg *config.Config, httpClient *http.Client, usageLogger usage.LoggerInterface) (*Result, error)
New creates the MCP gateway subsystem with its own storage connection.
type SQLiteStore ¶
type SQLiteStore struct {
// contains filtered or unexported fields
}
SQLiteStore stores managed MCP servers in SQLite.
func NewSQLiteStore ¶
func NewSQLiteStore(db *sql.DB) (*SQLiteStore, error)
NewSQLiteStore creates the mcp_servers table and indexes if needed.
func (*SQLiteStore) Close ¶
func (s *SQLiteStore) Close() error
func (*SQLiteStore) Get ¶
func (s *SQLiteStore) Get(ctx context.Context, name string) (*ManagedServer, error)
func (*SQLiteStore) List ¶
func (s *SQLiteStore) List(ctx context.Context) ([]ManagedServer, error)
func (*SQLiteStore) Upsert ¶
func (s *SQLiteStore) Upsert(ctx context.Context, server ManagedServer) error
type ServerSpec ¶
type ServerSpec struct {
// Name is the stable ASCII slug used for routing and namespacing.
Name string
DisplayName string
URL string
Transport string
Headers map[string]string
Command string
Args []string
Env map[string]string
Description string
Enabled bool
AllowedTools []string
DisallowedTools []string
UserPaths []string
ToolTimeout time.Duration
// Managed marks specs declared in config.yaml / MCP_SERVERS. They override
// admin-store rows with the same name and are read-only in the dashboard.
Managed bool
}
ServerSpec is the runtime-normalized definition of one upstream server, merged from declarative config (Managed=true) and the admin store.
func SpecFromConfig ¶
func SpecFromConfig(name string, cfg config.MCPServerConfig) ServerSpec
SpecFromConfig converts one declarative config entry into a runtime spec.
type ServerStatus ¶
type ServerStatus string
ServerStatus describes the runtime connection state of one upstream server.
const ( // StatusDisabled means the server is declared but switched off. StatusDisabled ServerStatus = "disabled" // StatusConnecting means no session has been established yet. StatusConnecting ServerStatus = "connecting" // StatusConnected means the session is live and the catalog is fresh. StatusConnected ServerStatus = "connected" // StatusDegraded means the last connect or listing failed; any previous // catalog is kept (stale carry-forward) and the server is re-probed. StatusDegraded ServerStatus = "degraded" )
type ServerView ¶
type ServerView struct {
Spec ServerSpec
Status ServerStatus
LastError string
ToolCount int
PromptCount int
// ResourceCount includes resource templates.
ResourceCount int
ConnectedAt time.Time
}
ServerView is a point-in-time snapshot of one upstream for admin and dashboard consumption.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service is the MCP gateway: it merges declarative and admin-store server specs into the upstream manager and serves the downstream MCP endpoints.
func NewService ¶
NewService builds the gateway service and starts connecting to the merged server set. Upstream connects are asynchronous; construction never blocks.
func (*Service) Catalog ¶
func (s *Service) Catalog(name string) (CatalogView, bool)
Catalog returns the current catalog snapshot for one server, for the admin API and dashboard inspector. ok is false for unknown server names; a known server that has never listed successfully returns empty (non-nil) lists.
func (*Service) Close ¶
func (s *Service) Close()
Close stops background work, terminates upstream sessions, and cancels downstream HTTP exchanges. Streamable HTTP clients keep a GET request open for server events, so those request contexts must be ended before the HTTP server can complete its graceful drain.
func (*Service) GetManaged ¶
GetManaged returns one admin-managed server row from the store. Config- declared servers are not store rows, so they (and a missing store) report ErrNotFound.
func (*Service) Reload ¶
Reload re-merges declarative and store specs and reconciles the upstream set. Declarative entries shadow store rows with the same name, mirroring the tagging/virtual-models source precedence.
func (*Service) ServeHTTP ¶
ServeHTTP handles one downstream MCP HTTP exchange. pinnedServer is the /mcp/{server} path segment ("" for the aggregated endpoint). Gateway authentication has already run; this layer enforces session-to-principal binding and stamps the internal identity headers tool handlers read.
func (*Service) Upsert ¶
func (s *Service) Upsert(ctx context.Context, server ManagedServer) error
Upsert validates and persists one admin-managed server, then reconciles. Config-declared names are read-only; stdio definitions are rejected at the store boundary (declarative-only by design — see the gateway spec).
func (*Service) Views ¶
func (s *Service) Views() []ServerView
Views returns the current admin snapshot of all servers.
type Store ¶
type Store interface {
List(ctx context.Context) ([]ManagedServer, error)
Get(ctx context.Context, name string) (*ManagedServer, error)
Upsert(ctx context.Context, server ManagedServer) error
Delete(ctx context.Context, name string) error
Close() error
}
Store defines persistence operations for admin-managed MCP servers.