Documentation
¶
Index ¶
- Constants
- Variables
- func ParsePrefixedTool(prefixed string) (agentName, toolName string, err error)
- func PrefixTool(agentName, toolName string) string
- func Transpile(code string) (string, error)
- type AgentClient
- type AutoscalePolicy
- type AutoscaleStatus
- type Autoscaler
- func (a *Autoscaler) Name() string
- func (a *Autoscaler) Policy() AutoscalePolicy
- func (a *Autoscaler) Set() *ReplicaSet
- func (a *Autoscaler) Status() AutoscaleStatus
- func (a *Autoscaler) Tick(ctx context.Context, now time.Time) (Decision, error)
- func (a *Autoscaler) TriggerColdStart(ctx context.Context) error
- func (a *Autoscaler) UpdatePolicy(p AutoscalePolicy)
- type Capabilities
- type Client
- type ClientBase
- func (b *ClientBase) AllTools() []Tool
- func (b *ClientBase) IsInitialized() bool
- func (b *ClientBase) ServerInfo() ServerInfo
- func (b *ClientBase) SetInitialized(info ServerInfo)
- func (b *ClientBase) SetToolWhitelist(tools []string)
- func (b *ClientBase) SetTools(tools []Tool)
- func (b *ClientBase) Tools() []Tool
- type ClientInfo
- type CodeMode
- func (cm *CodeMode) HandleCall(ctx context.Context, params ToolCallParams, caller ToolCaller, allTools []Tool) (*ToolCallResult, error)
- func (cm *CodeMode) HandleCallWithScope(ctx context.Context, params ToolCallParams, caller ToolCaller, ...) (*ToolCallResult, error)
- func (cm *CodeMode) IsMetaTool(name string) bool
- func (cm *CodeMode) SetLogger(logger *slog.Logger)
- func (cm *CodeMode) ToolsList() *ToolsListResult
- type Content
- type Decision
- type ExecuteResult
- type FetchConfig
- type FormatSavingsRecorder
- type Gateway
- func (g *Gateway) Autoscalers() []*Autoscaler
- func (g *Gateway) BuildAgentClient(ctx context.Context, cfg MCPServerConfig) (AgentClient, error)
- func (g *Gateway) CallTool(ctx context.Context, name string, arguments map[string]any) (*ToolCallResult, error)
- func (g *Gateway) Close()
- func (g *Gateway) CodeModeStatus() string
- func (g *Gateway) GetAutoscaler(serverName string) *Autoscaler
- func (g *Gateway) GetHealthStatus(name string) *HealthStatus
- func (g *Gateway) HandleInitialize(params InitializeParams) (*InitializeResult, *Session, error)
- func (g *Gateway) HandlePromptsGet(params PromptsGetParams) (*PromptsGetResult, error)
- func (g *Gateway) HandlePromptsList() (*PromptsListResult, error)
- func (g *Gateway) HandleResourcesList() (*ResourcesListResult, error)
- func (g *Gateway) HandleResourcesRead(params ResourcesReadParams) (*ResourcesReadResult, error)
- func (g *Gateway) HandleToolsCall(ctx context.Context, params ToolCallParams) (*ToolCallResult, error)
- func (g *Gateway) HandleToolsList() (*ToolsListResult, error)
- func (g *Gateway) RefreshAllTools(ctx context.Context) error
- func (g *Gateway) RegisterAutoscaler(ctx context.Context, template MCPServerConfig, policy string, spawner Spawner, ...) error
- func (g *Gateway) RegisterMCPReplicaSet(ctx context.Context, name, policy string, cfgs []MCPServerConfig) error
- func (g *Gateway) RegisterMCPServer(ctx context.Context, cfg MCPServerConfig) error
- func (g *Gateway) ReplicaStatuses(serverName string) []ReplicaStatus
- func (g *Gateway) ResetServerPins(serverName string) error
- func (g *Gateway) RestartMCPServer(ctx context.Context, name string) error
- func (g *Gateway) Router() *Router
- func (g *Gateway) ServerInfo() ServerInfo
- func (g *Gateway) SessionCount() int
- func (g *Gateway) Sessions() *SessionManager
- func (g *Gateway) SetCodeMode(timeout time.Duration)
- func (g *Gateway) SetDefaultOutputFormat(format string)
- func (g *Gateway) SetDockerClient(cli dockerclient.DockerClient)
- func (g *Gateway) SetFormatSavingsRecorder(recorder FormatSavingsRecorder)
- func (g *Gateway) SetLogger(logger *slog.Logger)
- func (g *Gateway) SetMaxToolResultBytes(n int)
- func (g *Gateway) SetSchemaVerifier(sv SchemaVerifier, action string)
- func (g *Gateway) SetServerMeta(cfg MCPServerConfig)
- func (g *Gateway) SetTokenCounter(counter token.Counter)
- func (g *Gateway) SetToolCallObserver(obs ToolCallObserver)
- func (g *Gateway) SetVersion(version string)
- func (g *Gateway) StartAutoscaler(ctx context.Context, interval time.Duration)
- func (g *Gateway) StartCleanup(ctx context.Context)
- func (g *Gateway) StartHealthMonitor(ctx context.Context, interval time.Duration)
- func (g *Gateway) Status() []MCPServerStatus
- func (g *Gateway) UnblockServer(serverName string)
- func (g *Gateway) UnregisterMCPServer(name string)
- type Handler
- type HealthStatus
- type InitializeParams
- type InitializeResult
- type InputSchemaObject
- type MCPPrompt
- type MCPResource
- type MCPServerConfig
- type MCPServerStatus
- type OpenAPIClient
- func (c *OpenAPIClient) CallTool(ctx context.Context, name string, args map[string]any) (*ToolCallResult, error)
- func (c *OpenAPIClient) Initialize(ctx context.Context) error
- func (c *OpenAPIClient) Name() string
- func (c *OpenAPIClient) Ping(ctx context.Context) error
- func (c *OpenAPIClient) RefreshTools(ctx context.Context) error
- func (c *OpenAPIClient) SetLogger(logger *slog.Logger)
- func (c *OpenAPIClient) SetPingTimeout(d time.Duration)
- type OpenAPIClientConfig
- type OpenAPIOperation
- type PinResetter
- type Pingable
- type ProcessClient
- func (c *ProcessClient) Close() error
- func (c *ProcessClient) Connect(ctx context.Context) error
- func (c *ProcessClient) PID() int
- func (c *ProcessClient) Ping(ctx context.Context) error
- func (c *ProcessClient) Reconnect(ctx context.Context) error
- func (c *ProcessClient) SetPingTimeout(d time.Duration)
- type PromptArgument
- type PromptArgumentData
- type PromptData
- type PromptMessage
- type PromptProvider
- type PromptsCapability
- type PromptsGetParams
- type PromptsGetResult
- type PromptsListResult
- type Property
- type RPCClient
- func (r *RPCClient) CallTool(ctx context.Context, name string, arguments map[string]any) (*ToolCallResult, error)
- func (r *RPCClient) Initialize(ctx context.Context) error
- func (r *RPCClient) Name() string
- func (r *RPCClient) RefreshTools(ctx context.Context) error
- func (r *RPCClient) SetLogger(logger *slog.Logger)
- type Reconnectable
- type Replica
- func (r *Replica) Client() AgentClient
- func (r *Replica) DecInFlight()
- func (r *Replica) Healthy() bool
- func (r *Replica) ID() int
- func (r *Replica) InFlight() int64
- func (r *Replica) IncInFlight()
- func (r *Replica) MarkStarted(now time.Time)
- func (r *Replica) Restart() *backoffState
- func (r *Replica) SetHealthy(h bool)
- func (r *Replica) StartedAt() time.Time
- type ReplicaSet
- func (s *ReplicaSet) AddReplica(client AgentClient) int
- func (s *ReplicaSet) CachedTools() []Tool
- func (s *ReplicaSet) Client() AgentClient
- func (s *ReplicaSet) HealthyCount() int
- func (s *ReplicaSet) MedianInFlight() float64
- func (s *ReplicaSet) Name() string
- func (s *ReplicaSet) Pick() (*Replica, error)
- func (s *ReplicaSet) Policy() string
- func (s *ReplicaSet) ReinsertReplica(r *Replica)
- func (s *ReplicaSet) RemoveReplica(id int) (*Replica, error)
- func (s *ReplicaSet) Replicas() []*Replica
- func (s *ReplicaSet) SetToolCache(tools []Tool)
- func (s *ReplicaSet) Size() int
- type ReplicaStatus
- type ResourceContents
- type ResourcesCapability
- type ResourcesListResult
- type ResourcesReadParams
- type ResourcesReadResult
- type Router
- func (r *Router) AddClient(client AgentClient)
- func (r *Router) AddReplicaSet(set *ReplicaSet)
- func (r *Router) AggregatedTools() []Tool
- func (r *Router) Clients() []AgentClient
- func (r *Router) GetClient(name string) AgentClient
- func (r *Router) GetReplicaSet(name string) *ReplicaSet
- func (r *Router) RefreshTools()
- func (r *Router) RemoveClient(name string)
- func (r *Router) ReplicaSets() []*ReplicaSet
- func (r *Router) RouteToolCall(prefixedName string) (AgentClient, string, error)
- func (r *Router) RouteToolCallReplica(prefixedName string) (*Replica, string, error)
- type SSEServer
- type Sandbox
- type SchemaDrift
- type SchemaVerifier
- type SearchIndex
- type ServerInfo
- type Session
- type SessionManager
- func (m *SessionManager) Cleanup(maxAge time.Duration) int
- func (m *SessionManager) Count() int
- func (m *SessionManager) Create(clientInfo ClientInfo) *Session
- func (m *SessionManager) Delete(id string)
- func (m *SessionManager) Get(id string) *Session
- func (m *SessionManager) List() []*Session
- func (m *SessionManager) Touch(id string)
- type Spawner
- type StdioClient
- func (c *StdioClient) Close() error
- func (c *StdioClient) Connect(ctx context.Context) error
- func (c *StdioClient) ContainerID() string
- func (c *StdioClient) Ping(ctx context.Context) error
- func (c *StdioClient) Reconnect(ctx context.Context) error
- func (c *StdioClient) SetPingTimeout(d time.Duration)
- type StreamableHTTPServer
- type StreamableSession
- type Tool
- type ToolCallObserver
- type ToolCallParams
- type ToolCallResult
- type ToolCaller
- type ToolsCapability
- type ToolsListResult
- type Transport
Constants ¶
const ( ReplicaPolicyRoundRobin = "round-robin" ReplicaPolicyLeastConnections = "least-connections" )
Dispatch policies for a ReplicaSet.
const ( // DefaultRequestTimeout is the timeout for individual MCP JSON-RPC requests. DefaultRequestTimeout = 30 * time.Second // DefaultReadyPollInterval is the interval between readiness checks. DefaultReadyPollInterval = 500 * time.Millisecond // DefaultReadyTimeout is the overall timeout for server readiness. DefaultReadyTimeout = 30 * time.Second )
Default timeouts for MCP transport clients.
const DefaultAutoscalerInterval = 10 * time.Second
DefaultAutoscalerInterval is the tick cadence Gateway.StartAutoscaler uses when callers pass 0. Kept short enough that reap/spawn latencies are observable; the per-direction cooldowns (ScaleUpAfter / ScaleDownAfter) gate actual actions so a 10s tick does not cause flapping.
const DefaultCodeModeTimeout = 30 * time.Second
DefaultCodeModeTimeout is the default code mode execution timeout.
const DefaultFetchMaxResponseBytes = 1 * 1024 * 1024
DefaultFetchMaxResponseBytes is the default response size cap (1MB).
const DefaultFetchRequestTimeout = 10 * time.Second
DefaultFetchRequestTimeout is the per-request timeout for fetch calls.
const DefaultHealthCheckInterval = 30 * time.Second
DefaultHealthCheckInterval is the default interval between health checks.
const DefaultPingTimeout = 5 * time.Second
DefaultPingTimeout is the timeout for health check pings.
const MCPProtocolVersion = "2025-11-25"
MCPProtocolVersion is the MCP protocol version supported by this implementation.
const MaxCodeSize = 64 * 1024
MaxCodeSize is the maximum allowed code input size (64KB).
const MaxRequestBodySize = 1 * 1024 * 1024
MaxRequestBodySize is the maximum allowed size for incoming JSON-RPC request bodies (1MB).
const MetaToolExecute = "execute"
MetaToolExecute is the name of the execute meta-tool.
const MetaToolSearch = "search"
MetaToolSearch is the name of the search meta-tool.
const ToolNameDelimiter = "__"
ToolNameDelimiter is the separator between agent name and tool name in prefixed tool names. Format: "agentname__toolname" Uses double underscore to be compatible with Claude Desktop's tool name validation: ^[a-zA-Z0-9_-]{1,64}$
Variables ¶
var ErrNoHealthyReplicas = errors.New("no healthy replicas")
ErrNoHealthyReplicas is returned by ReplicaSet.Pick when every replica in the set is marked unhealthy.
var ErrReadyTimeout = errors.New("ready timeout")
ErrReadyTimeout indicates that an HTTP/SSE MCP server did not become reachable within the configured readiness window. Callers can use errors.Is to distinguish this from context cancellation or other registration errors.
Functions ¶
func ParsePrefixedTool ¶
ParsePrefixedTool parses a prefixed tool name into agent and tool names.
func PrefixTool ¶
PrefixTool creates a prefixed tool name: "agent__tool"
Types ¶
type AgentClient ¶
type AgentClient interface {
Name() string
Initialize(ctx context.Context) error
RefreshTools(ctx context.Context) error
Tools() []Tool
CallTool(ctx context.Context, name string, arguments map[string]any) (*ToolCallResult, error)
IsInitialized() bool
ServerInfo() ServerInfo
}
AgentClient is the interface for communicating with MCP agents.
type AutoscalePolicy ¶
type AutoscalePolicy struct {
Min int // Minimum healthy replica count (>= 0; 0 only when IdleToZero).
Max int // Upper bound on replica count (>= 1).
TargetInFlight int // Per-replica in-flight request the scaler holds the median at or below.
ScaleUpAfter time.Duration // Window median must exceed target for at least this long.
ScaleDownAfter time.Duration // Window median must be below the target for at least this long.
WarmPool int // Extra replicas kept above the load-derived target.
IdleToZero bool // When true, Min may be 0; zero-scale reaps happen after ScaleDownAfter of no traffic.
}
AutoscalePolicy controls reactive autoscaling for a single ReplicaSet. Values are a snapshot; use Autoscaler.UpdatePolicy to swap in a new one without restarting the scaler loop.
type AutoscaleStatus ¶
type AutoscaleStatus struct {
Min int `json:"min"`
Max int `json:"max"`
Current int `json:"current"`
Target int `json:"target"`
TargetInFlight int `json:"targetInFlight"`
MedianInFlight int64 `json:"medianInFlight"`
LastScaleUpAt *time.Time `json:"lastScaleUpAt,omitempty"`
LastScaleDownAt *time.Time `json:"lastScaleDownAt,omitempty"`
LastDecision string `json:"lastDecision"`
WarmPool int `json:"warmPool,omitempty"`
IdleToZero bool `json:"idleToZero,omitempty"`
}
AutoscaleStatus is the serialisable snapshot included in MCPServerStatus when a server has autoscale configured. Fields mirror the spec in new_feature.md § "Observability surface".
type Autoscaler ¶
type Autoscaler struct {
// contains filtered or unexported fields
}
Autoscaler runs the scale-up / scale-down decision loop for one ReplicaSet. The ReplicaSet and Spawner are both injected so the decision logic can be tested against in-memory fakes.
func NewAutoscaler ¶
func NewAutoscaler(name string, set *ReplicaSet, spawner Spawner, policy AutoscalePolicy, logger *slog.Logger) *Autoscaler
NewAutoscaler builds an Autoscaler bound to a ReplicaSet and Spawner. The policy is applied immediately; subsequent UpdatePolicy calls swap it atomically. The initial rolling window is max(30s, ScaleUpAfter/2).
func (*Autoscaler) Name ¶
func (a *Autoscaler) Name() string
Name returns the logical server name this scaler manages.
func (*Autoscaler) Policy ¶
func (a *Autoscaler) Policy() AutoscalePolicy
Policy returns the current policy snapshot.
func (*Autoscaler) Status ¶
func (a *Autoscaler) Status() AutoscaleStatus
Status returns a snapshot of scaler state for the /api/stack/health payload. Returns zeroed timestamps until the corresponding action has occurred.
func (*Autoscaler) Tick ¶
Tick runs one evaluation cycle. Safe to call concurrently with tool dispatch. Returns the decision and any spawn/reap error. Errors are also logged at WARN so operators see them in the structured log stream.
func (*Autoscaler) TriggerColdStart ¶
func (a *Autoscaler) TriggerColdStart(ctx context.Context) error
TriggerColdStart spawns the first replica synchronously. Used by HandleToolsCall when a tool call arrives while the set is at zero replicas under an idle-to-zero policy. Returns nil once at least one replica has been added (including concurrently by another caller that won the race). Holds a.spawnMu so a racing periodic Tick cannot spawn in parallel.
func (*Autoscaler) UpdatePolicy ¶
func (a *Autoscaler) UpdatePolicy(p AutoscalePolicy)
UpdatePolicy swaps the active policy atomically and resizes the rolling window to match the new ScaleUpAfter. Called by the reload handler on policy-only changes so the next tick applies the new shape.
type Capabilities ¶
type Capabilities struct {
Tools *ToolsCapability `json:"tools,omitempty"`
Resources *ResourcesCapability `json:"resources,omitempty"`
Prompts *PromptsCapability `json:"prompts,omitempty"`
}
Capabilities describes what the server/client can do.
type Client ¶
type Client struct {
RPCClient
// contains filtered or unexported fields
}
Client communicates with a downstream MCP server.
func (*Client) SetPingTimeout ¶
SetPingTimeout overrides the per-ping deadline used by Ping. Zero restores the default (DefaultPingTimeout).
type ClientBase ¶
type ClientBase struct {
// contains filtered or unexported fields
}
ClientBase provides shared state and accessor methods for all AgentClient implementations. Embed this struct to get Tools(), IsInitialized(), ServerInfo(), and SetToolWhitelist().
The embedded tool list stores every tool the downstream server advertises (post include/exclude for OpenAPI, raw otherwise). The whitelist filter is applied at read time by Tools() so operators can widen the whitelist beyond the currently-exposed subset without losing the superset.
func (*ClientBase) AllTools ¶
func (b *ClientBase) AllTools() []Tool
AllTools returns every tool the downstream server advertises, ignoring any configured whitelist. Used by the management UI so operators can see the full selectable set regardless of the currently-applied curation.
func (*ClientBase) IsInitialized ¶
func (b *ClientBase) IsInitialized() bool
IsInitialized returns whether the client has been initialized.
func (*ClientBase) ServerInfo ¶
func (b *ClientBase) ServerInfo() ServerInfo
ServerInfo returns the server information.
func (*ClientBase) SetInitialized ¶
func (b *ClientBase) SetInitialized(info ServerInfo)
SetInitialized marks the client as initialized with the given server info.
func (*ClientBase) SetToolWhitelist ¶
func (b *ClientBase) SetToolWhitelist(tools []string)
SetToolWhitelist sets the list of allowed tool names. Only tools in this list will be returned by Tools() and RefreshTools(). An empty or nil list means all tools are allowed.
func (*ClientBase) SetTools ¶
func (b *ClientBase) SetTools(tools []Tool)
SetTools updates the cached tools. The full set is retained; the whitelist filter is applied on read by Tools().
func (*ClientBase) Tools ¶
func (b *ClientBase) Tools() []Tool
Tools returns the cached tool list filtered by the whitelist, if any. This is what the router exposes to LLM clients.
type ClientInfo ¶
ClientInfo contains information about the MCP client.
type CodeMode ¶
type CodeMode struct {
// contains filtered or unexported fields
}
CodeMode orchestrates search and execute operations for code mode. When active, it replaces individual tool definitions with two meta-tools (search and execute) that allow LLM agents to discover and call tools via JavaScript code in a sandboxed goja runtime.
func NewCodeMode ¶
NewCodeMode creates a new CodeMode instance with the given execution timeout.
func (*CodeMode) HandleCall ¶
func (cm *CodeMode) HandleCall(ctx context.Context, params ToolCallParams, caller ToolCaller, allTools []Tool) (*ToolCallResult, error)
HandleCall handles a code mode tool call with the full tool set.
func (*CodeMode) HandleCallWithScope ¶
func (cm *CodeMode) HandleCallWithScope(ctx context.Context, params ToolCallParams, caller ToolCaller, allowedTools []Tool) (*ToolCallResult, error)
HandleCallWithScope handles a code mode tool call with a scoped tool set. The allowedTools parameter controls which tools are available in the sandbox.
func (*CodeMode) IsMetaTool ¶
IsMetaTool returns true if the tool name is a code mode meta-tool.
func (*CodeMode) ToolsList ¶
func (cm *CodeMode) ToolsList() *ToolsListResult
ToolsList returns the two meta-tools (search and execute).
type Content ¶
Content represents content in a tool response.
func NewTextContent ¶
NewTextContent creates a text content item.
type ExecuteResult ¶
type ExecuteResult struct {
Value string // Return value (JSON-encoded)
Console []string // Captured console.log/warn/error output
}
ExecuteResult contains the output of a sandbox execution.
type FetchConfig ¶
type FetchConfig struct {
// HTTPSOnly rejects plain http:// URLs when true (default: true).
HTTPSOnly bool
// MaxResponseBytes caps the response body size. Default: 1MB.
MaxResponseBytes int64
// RequestTimeout is the per-request timeout. Default: 10s.
RequestTimeout time.Duration
// AllowPrivateNetworks disables the SSRF IP blocklist. For testing only.
AllowPrivateNetworks bool
}
FetchConfig holds operator-configurable settings for the sandboxed fetch client.
func DefaultFetchConfig ¶
func DefaultFetchConfig() FetchConfig
DefaultFetchConfig returns a FetchConfig with secure defaults.
type FormatSavingsRecorder ¶
type FormatSavingsRecorder interface {
// RecordFormatSavings records token counts before and after format conversion.
// originalTokens is the token count of the original JSON content.
// formattedTokens is the token count of the converted content (TOON/CSV).
RecordFormatSavings(serverName string, originalTokens, formattedTokens int)
}
FormatSavingsRecorder receives format savings observations. Used by the gateway to report token savings from format conversion without coupling to the metrics package directly. Normal token usage tracking is handled separately by the ToolCallObserver.
type Gateway ¶
type Gateway struct {
// contains filtered or unexported fields
}
Gateway aggregates multiple MCP servers into a single endpoint.
func (*Gateway) Autoscalers ¶
func (g *Gateway) Autoscalers() []*Autoscaler
Autoscalers returns a snapshot slice of every registered autoscaler, sorted by server name for deterministic iteration in the tick loop.
func (*Gateway) BuildAgentClient ¶
func (g *Gateway) BuildAgentClient(ctx context.Context, cfg MCPServerConfig) (AgentClient, error)
BuildAgentClient creates, connects, and initializes an AgentClient from a single MCPServerConfig. It does NOT touch serverMeta, pins, health, or the router — callers compose that separately. Exported so Spawner implementations in pkg/controller can reuse the transport switch rather than duplicating it.
func (*Gateway) CallTool ¶
func (g *Gateway) CallTool(ctx context.Context, name string, arguments map[string]any) (*ToolCallResult, error)
CallTool implements the ToolCaller interface, allowing components to call tools through the gateway without a direct reference to the router.
func (*Gateway) Close ¶
func (g *Gateway) Close()
Close stops the cleanup goroutine and closes all agent client connections.
func (*Gateway) CodeModeStatus ¶
CodeModeStatus returns the code mode status string ("off" or "on").
func (*Gateway) GetAutoscaler ¶
func (g *Gateway) GetAutoscaler(serverName string) *Autoscaler
GetAutoscaler returns the autoscaler registered for serverName, or nil if the server is not autoscaled.
func (*Gateway) GetHealthStatus ¶
func (g *Gateway) GetHealthStatus(name string) *HealthStatus
GetHealthStatus returns the health status for a named MCP server. Returns nil if no health data is available.
func (*Gateway) HandleInitialize ¶
func (g *Gateway) HandleInitialize(params InitializeParams) (*InitializeResult, *Session, error)
HandleInitialize handles the initialize request. It creates a new session and returns both the result and the session so callers can use the session ID.
func (*Gateway) HandlePromptsGet ¶
func (g *Gateway) HandlePromptsGet(params PromptsGetParams) (*PromptsGetResult, error)
HandlePromptsGet returns a specific prompt with argument substitution.
func (*Gateway) HandlePromptsList ¶
func (g *Gateway) HandlePromptsList() (*PromptsListResult, error)
HandlePromptsList returns all active prompts as MCP Prompts.
func (*Gateway) HandleResourcesList ¶
func (g *Gateway) HandleResourcesList() (*ResourcesListResult, error)
HandleResourcesList returns prompts as MCP Resources.
func (*Gateway) HandleResourcesRead ¶
func (g *Gateway) HandleResourcesRead(params ResourcesReadParams) (*ResourcesReadResult, error)
HandleResourcesRead returns the content of a prompt resource.
func (*Gateway) HandleToolsCall ¶
func (g *Gateway) HandleToolsCall(ctx context.Context, params ToolCallParams) (*ToolCallResult, error)
HandleToolsCall routes a tool call to the appropriate MCP server. When code mode is active and the tool is a meta-tool, delegates to code mode.
func (*Gateway) HandleToolsList ¶
func (g *Gateway) HandleToolsList() (*ToolsListResult, error)
HandleToolsList returns all aggregated tools. When code mode is active, returns the two meta-tools instead.
func (*Gateway) RefreshAllTools ¶
RefreshAllTools refreshes tools from all registered MCP servers.
func (*Gateway) RegisterAutoscaler ¶
func (g *Gateway) RegisterAutoscaler(ctx context.Context, template MCPServerConfig, policy string, spawner Spawner, autoscale AutoscalePolicy) error
RegisterAutoscaler registers an autoscaled replica set for an MCP server. The Spawner owns replica provisioning; the gateway only stores metadata and wires the scaler into the router. One synchronous Tick is executed before returning so Min (and WarmPool) replicas are available before the caller's first tool call — except when IdleToZero=true and Min=0, in which case the first tool call triggers a cold-start spawn instead.
func (*Gateway) RegisterMCPReplicaSet ¶
func (g *Gateway) RegisterMCPReplicaSet(ctx context.Context, name, policy string, cfgs []MCPServerConfig) error
RegisterMCPReplicaSet initializes one AgentClient per config and registers them as a single replica set under the given server name. All configs must be for the same logical server (same Name, same transport, same tool list); only the per-replica runtime handles (ContainerID / Endpoint) should differ. For len(cfgs) == 1 this is byte-identical to the old single-client path.
Partial-startup tolerance: if some replicas fail to initialize, the server is still registered with the successful ones. The call only returns an error when every replica failed, or when the single-replica case fails (in which case the caller sees the same error shape as before).
func (*Gateway) RegisterMCPServer ¶
func (g *Gateway) RegisterMCPServer(ctx context.Context, cfg MCPServerConfig) error
RegisterMCPServer registers and initializes a single-replica MCP server. Equivalent to RegisterMCPReplicaSet with one config and round-robin policy.
func (*Gateway) ReplicaStatuses ¶
func (g *Gateway) ReplicaStatuses(serverName string) []ReplicaStatus
ReplicaStatuses returns per-replica status for the named server, ordered by replica id. Returns nil if the server is not registered.
func (*Gateway) ResetServerPins ¶
ResetServerPins clears the stored pin record for serverName, if the wired SchemaVerifier also implements PinResetter. Called before re-registering a modified server during hot reload so the next VerifyOrPin re-pins from scratch rather than flagging config-driven tool changes as drift.
func (*Gateway) RestartMCPServer ¶
RestartMCPServer restarts an individual MCP server by name. It tears down the existing connection, optionally restarts the container (for stdio transport), and re-registers the server using its stored config.
func (*Gateway) ServerInfo ¶
func (g *Gateway) ServerInfo() ServerInfo
ServerInfo returns the gateway server info.
func (*Gateway) SessionCount ¶
SessionCount returns the number of active sessions.
func (*Gateway) Sessions ¶
func (g *Gateway) Sessions() *SessionManager
Sessions returns the session manager.
func (*Gateway) SetCodeMode ¶
SetCodeMode enables code mode with the given timeout. When code mode is active, tools/list returns meta-tools instead of individual tools.
func (*Gateway) SetDefaultOutputFormat ¶
SetDefaultOutputFormat sets the gateway-level default output format.
func (*Gateway) SetDockerClient ¶
func (g *Gateway) SetDockerClient(cli dockerclient.DockerClient)
SetDockerClient sets the Docker client for stdio transport.
func (*Gateway) SetFormatSavingsRecorder ¶
func (g *Gateway) SetFormatSavingsRecorder(recorder FormatSavingsRecorder)
SetFormatSavingsRecorder sets the recorder for format savings metrics.
func (*Gateway) SetLogger ¶
SetLogger sets the logger for gateway operations. If nil is passed, logging is disabled (default).
func (*Gateway) SetMaxToolResultBytes ¶
SetMaxToolResultBytes sets the maximum tool result size in bytes before truncation. When set to 0, the default of 65536 (64KB) is used.
func (*Gateway) SetSchemaVerifier ¶
func (g *Gateway) SetSchemaVerifier(sv SchemaVerifier, action string)
SetSchemaVerifier wires in a SchemaVerifier for TOFU schema pinning. action must be "warn" (default) or "block".
func (*Gateway) SetServerMeta ¶
func (g *Gateway) SetServerMeta(cfg MCPServerConfig)
SetServerMeta stores metadata for an MCP server without connecting to it. This is used by tests and by internal registration paths that manage their own client connections.
func (*Gateway) SetTokenCounter ¶
SetTokenCounter sets the token counter used for format savings calculation.
func (*Gateway) SetToolCallObserver ¶
func (g *Gateway) SetToolCallObserver(obs ToolCallObserver)
SetToolCallObserver sets an observer that is notified after every tool call. Used to collect token usage metrics without coupling the gateway to a metrics package.
func (*Gateway) SetVersion ¶
SetVersion sets the gateway version string.
func (*Gateway) StartAutoscaler ¶
StartAutoscaler launches a background goroutine that ticks every registered autoscaler on the given interval. Cancelling ctx stops the loop. Safe to call alongside StartHealthMonitor and StartCleanup.
func (*Gateway) StartCleanup ¶
StartCleanup starts periodic session cleanup. Call Close() to stop.
func (*Gateway) StartHealthMonitor ¶
StartHealthMonitor starts periodic health checking for all registered MCP servers. It runs alongside StartCleanup and stops when the gateway context is cancelled.
func (*Gateway) Status ¶
func (g *Gateway) Status() []MCPServerStatus
Status returns status of all registered MCP servers. Note: This only returns actual MCP servers, not A2A adapters or other clients added directly to the router.
func (*Gateway) UnblockServer ¶
UnblockServer clears the block on a server that was blocked due to schema drift. Called by the approve flow after the user accepts the updated tool definitions.
func (*Gateway) UnregisterMCPServer ¶
UnregisterMCPServer removes an MCP server from the gateway.
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler provides HTTP handlers for the MCP gateway.
func NewHandler ¶
NewHandler creates a new MCP HTTP handler.
type HealthStatus ¶
type HealthStatus struct {
Healthy bool // Whether the server is responding to pings
LastCheck time.Time // When the last health check ran
LastHealthy time.Time // When the server was last seen healthy
Error string // Error message if unhealthy (empty when healthy)
}
HealthStatus tracks the health state of a downstream MCP server.
type InitializeParams ¶
type InitializeParams struct {
ProtocolVersion string `json:"protocolVersion"`
ClientInfo ClientInfo `json:"clientInfo"`
Capabilities Capabilities `json:"capabilities"`
}
InitializeParams contains parameters for the initialize request.
type InitializeResult ¶
type InitializeResult struct {
ProtocolVersion string `json:"protocolVersion"`
ServerInfo ServerInfo `json:"serverInfo"`
Capabilities Capabilities `json:"capabilities"`
Instructions string `json:"instructions,omitempty"`
}
InitializeResult is the response to initialize.
type InputSchemaObject ¶
type InputSchemaObject struct {
Type string `json:"type"`
Properties map[string]Property `json:"properties,omitempty"`
Required []string `json:"required,omitempty"`
}
InputSchemaObject is a helper for building simple input schemas. Use this when creating tools programmatically (e.g., A2A skill adapters). For MCP tools received from servers, use json.RawMessage directly to preserve the full JSON Schema without loss.
type MCPPrompt ¶
type MCPPrompt struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
Arguments []PromptArgument `json:"arguments,omitempty"`
}
MCPPrompt represents a prompt in the MCP prompts/list response.
type MCPResource ¶
type MCPResource struct {
URI string `json:"uri"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
MimeType string `json:"mimeType,omitempty"`
}
MCPResource represents a resource in the resources/list response.
type MCPServerConfig ¶
type MCPServerConfig struct {
Name string
Transport Transport
Endpoint string // For HTTP/SSE transport
ContainerID string // For Docker Stdio transport
External bool // True for external URL servers (no container)
LocalProcess bool // True for local process servers (no container)
SSH bool // True for SSH servers (remote process over SSH)
OpenAPI bool // True for OpenAPI-based servers
Command []string // For local process or SSH transport
WorkDir string // For local process transport
Env map[string]string // For local process or SSH transport
SSHHost string // SSH hostname (for SSH servers)
SSHUser string // SSH username (for SSH servers)
SSHPort int // SSH port (for SSH servers, 0 = default 22)
SSHIdentityFile string // SSH identity file path (for SSH servers)
SSHKnownHostsFile string // SSH known_hosts file path; enables StrictHostKeyChecking=yes
SSHJumpHost string // SSH jump/bastion host ([user@]host[:port])
OpenAPIConfig *OpenAPIClientConfig // OpenAPI configuration (for OpenAPI servers)
Tools []string // Tool whitelist (empty = all tools)
OutputFormat string // Output format: "json", "toon", "csv", "text"
PinSchemas *bool // Override gateway schema pinning (nil = inherit gateway default)
// ReadyTimeout overrides the HTTP/SSE readiness wait. Zero uses DefaultReadyTimeout.
// Applies only to HTTP and SSE transports; stdio and other paths ignore it.
ReadyTimeout time.Duration
// PingTimeout overrides the per-ping deadline used by the health monitor.
// Zero uses DefaultPingTimeout. Useful for slow upstreams (e.g. HTTP servers
// with many tools) where the 5s default can flake under autoscale spawn load.
PingTimeout time.Duration
// CleanupOnReadyFailure runs when waitForHTTPServer returns ErrReadyTimeout.
// Callers that manage the underlying container populate this with a closure
// that stops and removes it, so a retry starts from a clean slate. nil means
// "no cleanup" (e.g. external servers, tests).
CleanupOnReadyFailure func(ctx context.Context) error
}
MCPServerConfig contains configuration for connecting to an MCP server.
type MCPServerStatus ¶
type MCPServerStatus struct {
Name string `json:"name"`
Transport Transport `json:"transport"`
Endpoint string `json:"endpoint,omitempty"`
ContainerID string `json:"containerId,omitempty"`
Initialized bool `json:"initialized"`
ToolCount int `json:"toolCount"`
Tools []string `json:"tools"`
External bool `json:"external"` // True for external URL servers
LocalProcess bool `json:"localProcess"` // True for local process servers
SSH bool `json:"ssh"` // True for SSH servers
SSHHost string `json:"sshHost,omitempty"` // SSH hostname
OpenAPI bool `json:"openapi"` // True for OpenAPI servers
OpenAPISpec string `json:"openapiSpec,omitempty"` // OpenAPI spec location
OutputFormat string `json:"outputFormat,omitempty"` // Configured output format (empty = json default)
Healthy *bool `json:"healthy,omitempty"` // Health check result (nil if not yet checked)
LastCheck *time.Time `json:"lastCheck,omitempty"` // When last health check ran
HealthError string `json:"healthError,omitempty"` // Error message if unhealthy
// ToolWhitelist is the tools: field from the stack YAML for this server.
// Empty (nil) means no whitelist is configured and the server is exposing
// every tool it advertises. The UI uses this to distinguish "curated" from
// "full-list" without needing to diff tools against a hidden pre-filter
// set that the gateway doesn't retain.
ToolWhitelist []string `json:"toolWhitelist,omitempty"`
Replicas []ReplicaStatus `json:"replicas,omitempty"` // Per-replica status; always populated
// Autoscale is non-nil only for servers with an autoscale block in
// their stack YAML. Reports current min/max/target/median and the
// last scaler decision so operators can reason about scale events.
Autoscale *AutoscaleStatus `json:"autoscale,omitempty"`
}
MCPServerStatus returns status information about registered MCP servers.
type OpenAPIClient ¶
type OpenAPIClient struct {
ClientBase
// contains filtered or unexported fields
}
OpenAPIClient implements AgentClient by transforming OpenAPI operations to MCP tools. It parses an OpenAPI specification and converts each operation into an MCP tool, proxying tool calls to HTTP requests against the target API.
func NewOpenAPIClient ¶
func NewOpenAPIClient(name string, cfg *OpenAPIClientConfig) (*OpenAPIClient, error)
NewOpenAPIClient creates an OpenAPI-based MCP client.
func (*OpenAPIClient) CallTool ¶
func (c *OpenAPIClient) CallTool(ctx context.Context, name string, args map[string]any) (*ToolCallResult, error)
CallTool executes an OpenAPI operation.
func (*OpenAPIClient) Initialize ¶
func (c *OpenAPIClient) Initialize(ctx context.Context) error
Initialize loads and parses the OpenAPI spec.
func (*OpenAPIClient) Ping ¶
func (c *OpenAPIClient) Ping(ctx context.Context) error
Ping checks if the OpenAPI backend is reachable by making a HEAD request to the base URL.
func (*OpenAPIClient) RefreshTools ¶
func (c *OpenAPIClient) RefreshTools(ctx context.Context) error
RefreshTools builds MCP tools from OpenAPI operations. OpenAPIClient applies config-time include/exclude filters here. The runtime whitelist is applied at read time by ClientBase.Tools(), so the full post-include/exclude set is cached to let the UI widen the whitelist.
func (*OpenAPIClient) SetLogger ¶
func (c *OpenAPIClient) SetLogger(logger *slog.Logger)
SetLogger sets the logger for this client.
func (*OpenAPIClient) SetPingTimeout ¶
func (c *OpenAPIClient) SetPingTimeout(d time.Duration)
SetPingTimeout overrides the per-ping deadline used by Ping. Zero restores the default (DefaultPingTimeout).
type OpenAPIClientConfig ¶
type OpenAPIClientConfig struct {
Spec string // URL or local file path to OpenAPI spec
BaseURL string // Override server URL from spec
AuthType string // "bearer", "header", "query", "oauth2", or "basic"
AuthToken string // Resolved bearer token (from env)
AuthHeader string // Header name for header-based auth
AuthValue string // Resolved header value (from env)
Include []string // Operation IDs to include
Exclude []string // Operation IDs to exclude
NoExpand bool // If true, skip environment variable expansion in spec file
// Query param auth fields
AuthQueryParam string // Query parameter name for type: query
AuthQueryValue string // Resolved query parameter value (from env)
// OAuth2 client credentials fields
OAuth2ClientID string // Resolved OAuth2 client ID (from env)
OAuth2ClientSecret string // Resolved OAuth2 client secret (from env)
OAuth2TokenURL string // OAuth2 token endpoint URL
OAuth2Scopes []string // OAuth2 scopes to request
// Basic auth fields
BasicUsername string // Resolved username (from env)
BasicPassword string // Resolved password (from env)
// TLS/mTLS fields
TLSCertFile string // Client certificate file path
TLSKeyFile string // Client private key file path
TLSCAFile string // Custom CA certificate file path
TLSInsecureSkipVerify bool // Skip server certificate verification
}
OpenAPIClientConfig contains configuration for an OpenAPI-backed MCP client.
type OpenAPIOperation ¶
type OpenAPIOperation struct {
Method string
Path string
PathParams []string // Parameter names in path order (always required)
QueryParams map[string]*openapi3.Parameter
HeaderParams map[string]*openapi3.Parameter
RequestBody *openapi3.RequestBodyRef
}
OpenAPIOperation holds parsed OpenAPI operation details for execution.
type PinResetter ¶
type PinResetter interface {
// ResetServerPins deletes the pin record for serverName so the next
// VerifyOrPin call treats it as a first-use pin.
ResetServerPins(serverName string) error
}
PinResetter is an optional extension of SchemaVerifier for clearing stored pin records. Implementations that support this (e.g. pins.GatewayAdapter) satisfy this interface. It is checked via type assertion, not embedded in SchemaVerifier, so existing implementations remain compatible.
type Pingable ¶
Pingable is an optional interface for AgentClients that support health checks. The health monitor uses type assertion to check if a client implements this.
type ProcessClient ¶
type ProcessClient struct {
RPCClient
// contains filtered or unexported fields
}
ProcessClient communicates with an MCP server via a local process stdin/stdout.
func NewProcessClient ¶
func NewProcessClient(name string, command []string, workDir string, env map[string]string) *ProcessClient
NewProcessClient creates a new process-based MCP client. The command is executed with the given working directory and environment. Environment variables are merged with the current process environment.
func (*ProcessClient) Close ¶
func (c *ProcessClient) Close() error
Close terminates the process gracefully. Sends SIGTERM, waits up to 5 seconds, then sends SIGKILL if still running.
func (*ProcessClient) Connect ¶
func (c *ProcessClient) Connect(ctx context.Context) error
Connect starts the process and attaches to its stdin/stdout.
func (*ProcessClient) PID ¶
func (c *ProcessClient) PID() int
PID returns the operating-system process id of the running child. Returns 0 when the process has not been started (or has exited and been cleared).
func (*ProcessClient) Ping ¶
func (c *ProcessClient) Ping(ctx context.Context) error
Ping checks if the process is alive by verifying it's still running and sending a JSON-RPC ping.
func (*ProcessClient) Reconnect ¶
func (c *ProcessClient) Reconnect(ctx context.Context) error
Reconnect terminates the existing process and starts a new one, including the MCP handshake and tool refresh. Thread-safe: concurrent callers will block until reconnection completes.
func (*ProcessClient) SetPingTimeout ¶
func (c *ProcessClient) SetPingTimeout(d time.Duration)
SetPingTimeout overrides the per-ping deadline used by Ping. Zero restores the default (DefaultPingTimeout).
type PromptArgument ¶
type PromptArgument struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
Required bool `json:"required,omitempty"`
}
PromptArgument describes a prompt parameter.
type PromptArgumentData ¶
PromptArgumentData describes a prompt argument with default value support.
type PromptData ¶
type PromptData struct {
Name string
Description string
Content string
Arguments []PromptArgumentData
}
PromptData contains prompt information used by the MCP protocol layer.
type PromptMessage ¶
type PromptMessage struct {
Role string `json:"role"` // "user" or "assistant"
Content Content `json:"content"`
}
PromptMessage represents a message in a prompts/get response.
type PromptProvider ¶
type PromptProvider interface {
ListPromptData() []PromptData
GetPromptData(name string) (*PromptData, error)
}
PromptProvider is an optional interface for AgentClients that manage prompts. The gateway uses type assertion to detect prompt-capable clients and serve the MCP prompts/* and resources/* protocol methods.
type PromptsCapability ¶
type PromptsCapability struct {
ListChanged bool `json:"listChanged,omitempty"`
}
PromptsCapability indicates prompts support.
type PromptsGetParams ¶
type PromptsGetParams struct {
Name string `json:"name"`
Arguments map[string]string `json:"arguments,omitempty"`
}
PromptsGetParams contains parameters for prompts/get.
type PromptsGetResult ¶
type PromptsGetResult struct {
Description string `json:"description,omitempty"`
Messages []PromptMessage `json:"messages"`
}
PromptsGetResult is the response to prompts/get.
type PromptsListResult ¶
type PromptsListResult struct {
Prompts []MCPPrompt `json:"prompts"`
}
PromptsListResult is the response to prompts/list.
type Property ¶
type Property struct {
Type string `json:"type"`
Description string `json:"description,omitempty"`
Enum []string `json:"enum,omitempty"`
Default any `json:"default,omitempty"`
}
Property describes a single property in an input schema.
type RPCClient ¶
type RPCClient struct {
ClientBase
// contains filtered or unexported fields
}
RPCClient provides shared JSON-RPC protocol methods for MCP transport clients. It embeds ClientBase for state management and delegates I/O to a transporter.
Embedding hierarchy: ConcreteClient -> RPCClient -> ClientBase
Each concrete client (Client, StdioClient, ProcessClient) embeds RPCClient and implements transporter, passing itself to initRPCClient. This allows the shared protocol methods to dispatch to transport-specific I/O.
OpenAPIClient is separate — it embeds ClientBase directly since it does not use JSON-RPC at all.
func (*RPCClient) CallTool ¶
func (r *RPCClient) CallTool(ctx context.Context, name string, arguments map[string]any) (*ToolCallResult, error)
CallTool invokes a tool on the downstream agent.
func (*RPCClient) Initialize ¶
Initialize performs the MCP initialize handshake. If the transport implements connector, Connect() is called first.
func (*RPCClient) RefreshTools ¶
RefreshTools fetches the current tool list from the agent. If a tool whitelist has been set, only tools matching the whitelist are stored.
type Reconnectable ¶
Reconnectable is an optional interface for AgentClients that support reconnection after connection failures (e.g., container restart, process crash). The health monitor uses type assertion to trigger reconnection on unhealthy clients.
type Replica ¶
type Replica struct {
// contains filtered or unexported fields
}
Replica is a single member of a ReplicaSet. It wraps one AgentClient (the concrete transport — ProcessClient, StdioClient, Client, etc.) and tracks liveness and in-flight request count for dispatch decisions.
func (*Replica) Client ¶
func (r *Replica) Client() AgentClient
Client returns the underlying AgentClient.
func (*Replica) DecInFlight ¶
func (r *Replica) DecInFlight()
DecInFlight decrements the in-flight request count.
func (*Replica) IncInFlight ¶
func (r *Replica) IncInFlight()
IncInFlight increments the in-flight request count.
func (*Replica) MarkStarted ¶
MarkStarted records the current time as the replica's start time. Called from NewReplicaSet and from the reconnect path so uptime reflects the lifetime of the currently-running backing process.
func (*Replica) Restart ¶
func (r *Replica) Restart() *backoffState
Restart returns the replica's restart-backoff state. Never nil.
func (*Replica) SetHealthy ¶
SetHealthy marks this replica healthy or unhealthy.
type ReplicaSet ¶
type ReplicaSet struct {
// contains filtered or unexported fields
}
ReplicaSet is a pool of AgentClient replicas for a single logical MCP server. Dispatch is determined by the set's policy. A single-replica set behaves identically to a direct AgentClient (its Pick always returns that one replica when healthy).
func NewReplicaSet ¶
func NewReplicaSet(name, policy string, clients []AgentClient) *ReplicaSet
NewReplicaSet builds a ReplicaSet from an ordered slice of AgentClients. The first client becomes replica-0, and so on. All replicas start healthy. An unknown policy falls back to round-robin. The id counter is seeded to len(clients) so dynamic adds never collide with static ids.
func (*ReplicaSet) AddReplica ¶
func (s *ReplicaSet) AddReplica(client AgentClient) int
AddReplica appends a new replica with a monotonically increasing id and marks it healthy. Returns the new replica's id. Ids are never reused so handles stored by observers (health monitor, status endpoints) remain stable across scale events.
func (*ReplicaSet) CachedTools ¶
func (s *ReplicaSet) CachedTools() []Tool
CachedTools returns a copy of the cached tool surface. Returns an empty slice when the cache has not been primed.
func (*ReplicaSet) Client ¶
func (s *ReplicaSet) Client() AgentClient
Client is a convenience that calls Pick and returns the chosen replica's AgentClient. Returns nil if no replica is pickable.
func (*ReplicaSet) HealthyCount ¶
func (s *ReplicaSet) HealthyCount() int
HealthyCount returns the number of replicas currently marked healthy.
func (*ReplicaSet) MedianInFlight ¶
func (s *ReplicaSet) MedianInFlight() float64
MedianInFlight returns the median of in-flight counters across currently healthy replicas. Returns 0 when no replica is healthy. Returns float64 for precision in small-scale clusters where one request can tilt the mean noticeably.
func (*ReplicaSet) Pick ¶
func (s *ReplicaSet) Pick() (*Replica, error)
Pick chooses a healthy replica according to the set's policy. Returns ErrNoHealthyReplicas if every replica is currently marked unhealthy.
func (*ReplicaSet) Policy ¶
func (s *ReplicaSet) Policy() string
Policy returns the dispatch policy in effect.
func (*ReplicaSet) ReinsertReplica ¶
func (s *ReplicaSet) ReinsertReplica(r *Replica)
ReinsertReplica puts a previously-removed replica back into the set without minting a new id. Used by the autoscaler when a drain fails so the in-flight counters and restart state the caller accumulated while the replica was detached are preserved. Idempotent: if a replica with the same id is already present, this is a no-op.
func (*ReplicaSet) RemoveReplica ¶
func (s *ReplicaSet) RemoveReplica(id int) (*Replica, error)
RemoveReplica removes the replica with the given id and returns it so the caller can close its client. Returns an error if the id is not present. The caller is responsible for policy checks (min floor, warm pool, etc.); this method only enforces that the replica exists.
func (*ReplicaSet) Replicas ¶
func (s *ReplicaSet) Replicas() []*Replica
Replicas returns a snapshot slice of the replicas. Callers may iterate the snapshot safely; the underlying *Replica values are shared.
func (*ReplicaSet) SetToolCache ¶
func (s *ReplicaSet) SetToolCache(tools []Tool)
SetToolCache replaces the tool-definition cache. Callers set this after every successful refresh so Router.AggregatedTools can fall back to the cached surface when every replica is currently reaped.
func (*ReplicaSet) Size ¶
func (s *ReplicaSet) Size() int
Size returns the number of replicas in the set.
type ReplicaStatus ¶
type ReplicaStatus struct {
ReplicaID int `json:"replicaId"`
State string `json:"state"` // "healthy" | "unhealthy" | "restarting"
Healthy bool `json:"healthy"`
InFlight int64 `json:"inFlight"`
StartedAt time.Time `json:"startedAt,omitempty"`
LastCheck *time.Time `json:"lastCheck,omitempty"`
LastHealthy *time.Time `json:"lastHealthy,omitempty"`
LastError string `json:"lastError,omitempty"`
RestartAttempts uint32 `json:"restartAttempts,omitempty"`
NextRetryAt *time.Time `json:"nextRetryAt,omitempty"`
PID int `json:"pid,omitempty"`
ContainerID string `json:"containerId,omitempty"`
}
ReplicaStatus reports the live state of a single replica within a ReplicaSet. Uptime is derived from StartedAt at read time by the consumer.
type ResourceContents ¶
type ResourceContents struct {
URI string `json:"uri"`
MimeType string `json:"mimeType,omitempty"`
Text string `json:"text,omitempty"`
}
ResourceContents represents the content of a resource.
type ResourcesCapability ¶
type ResourcesCapability struct {
Subscribe bool `json:"subscribe,omitempty"`
ListChanged bool `json:"listChanged,omitempty"`
}
ResourcesCapability indicates resources support.
type ResourcesListResult ¶
type ResourcesListResult struct {
Resources []MCPResource `json:"resources"`
}
ResourcesListResult is the response to resources/list.
type ResourcesReadParams ¶
type ResourcesReadParams struct {
URI string `json:"uri"`
}
ResourcesReadParams contains parameters for resources/read.
type ResourcesReadResult ¶
type ResourcesReadResult struct {
Contents []ResourceContents `json:"contents"`
}
ResourcesReadResult is the response to resources/read.
type Router ¶
type Router struct {
// contains filtered or unexported fields
}
Router routes tool calls to the appropriate agent.
Internally the Router keys on server name and stores a *ReplicaSet per name. A single-client registration (via AddClient) is wrapped in a single-replica round-robin set so callers outside this package observe the same behavior as before replicas existed.
func (*Router) AddClient ¶
func (r *Router) AddClient(client AgentClient)
AddClient adds an agent client to the router as a single-replica set. Preserves the pre-replicas API so existing callers keep working unchanged.
func (*Router) AddReplicaSet ¶
func (r *Router) AddReplicaSet(set *ReplicaSet)
AddReplicaSet registers a replica set under its logical server name. Replaces any existing set with the same name.
func (*Router) AggregatedTools ¶
AggregatedTools returns all tools from all agents with prefixed names.
func (*Router) Clients ¶
func (r *Router) Clients() []AgentClient
Clients returns one representative AgentClient per registered agent, sorted by agent name. Each representative is chosen via the set's policy, so a single-replica set returns its only client. Skips sets with no currently-healthy replica.
func (*Router) GetClient ¶
func (r *Router) GetClient(name string) AgentClient
GetClient returns one client for the named agent, chosen by the set's dispatch policy. Returns nil if the agent is not registered or no replica is currently healthy.
func (*Router) GetReplicaSet ¶
func (r *Router) GetReplicaSet(name string) *ReplicaSet
GetReplicaSet returns the replica set for the named agent, or nil if the agent is not registered. Useful for callers that need per-replica access (health monitor, status reporting).
func (*Router) RefreshTools ¶
func (r *Router) RefreshTools()
RefreshTools updates the tool registry from all agents.
func (*Router) RemoveClient ¶
RemoveClient removes an agent (replica set) and its tools from the router.
func (*Router) ReplicaSets ¶
func (r *Router) ReplicaSets() []*ReplicaSet
ReplicaSets returns all registered replica sets, sorted by agent name.
func (*Router) RouteToolCall ¶
func (r *Router) RouteToolCall(prefixedName string) (AgentClient, string, error)
RouteToolCall routes a tool call to the appropriate agent. The concrete replica is chosen by the set's dispatch policy.
func (*Router) RouteToolCallReplica ¶
RouteToolCallReplica behaves like RouteToolCall but returns the chosen replica itself. Callers that need the replica id (for per-replica logging, tracing, and in-flight accounting) should use this variant.
type SSEServer ¶
type SSEServer struct {
// contains filtered or unexported fields
}
SSEServer handles legacy SSE connections at /sse for backward-compatibility negotiation. Clients using the deprecated HTTP+SSE transport receive a negotiation response directing them to use the Streamable HTTP transport at POST /mcp.
func NewSSEServer ¶
NewSSEServer creates a new SSE server.
func (*SSEServer) Close ¶
func (s *SSEServer) Close()
Close is a no-op retained for interface compatibility.
func (*SSEServer) HandleMessage ¶
func (s *SSEServer) HandleMessage(w http.ResponseWriter, r *http.Request)
HandleMessage returns 410 Gone for the legacy /message endpoint. Clients should use the Streamable HTTP transport at /mcp instead.
func (*SSEServer) ServeHTTP ¶
func (s *SSEServer) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP handles GET /sse — sends a negotiation event directing the client to use the Streamable HTTP transport and closes the connection.
func (*SSEServer) SessionCount ¶
SessionCount returns 0; session management has moved to StreamableHTTPServer.
type Sandbox ¶
type Sandbox struct {
// contains filtered or unexported fields
}
Sandbox executes JavaScript code in a goja runtime with MCP tool bindings.
func NewSandbox ¶
NewSandbox creates a sandbox with the given execution timeout and default fetch config.
func NewSandboxWithConfig ¶
func NewSandboxWithConfig(timeout time.Duration, fetchConfig FetchConfig) *Sandbox
NewSandboxWithConfig creates a sandbox with the given execution timeout and fetch config.
func (*Sandbox) Execute ¶
func (s *Sandbox) Execute(ctx context.Context, code string, caller ToolCaller, allowedTools []Tool) (*ExecuteResult, error)
Execute runs JavaScript code in a fresh goja runtime with MCP tool bindings. The code is transpiled from modern JS to ES2015 before execution.
type SchemaDrift ¶
type SchemaDrift struct {
Name string
OldHash string
NewHash string
OldDescription string
NewDescription string
}
SchemaDrift describes a single tool whose definition changed since it was pinned.
type SchemaVerifier ¶
type SchemaVerifier interface {
// VerifyOrPin pins tools on first use and verifies them on subsequent calls.
// Returns the list of modified tools (empty = no drift) and any error.
VerifyOrPin(serverName string, tools []Tool) ([]SchemaDrift, error)
}
SchemaVerifier performs TOFU schema pinning for MCP tool definitions. It is defined in the mcp package (rather than importing pkg/pins) to avoid an import cycle: pkg/pins already imports pkg/mcp for the Tool type. pkg/pins.GatewayAdapter implements this interface.
type SearchIndex ¶
type SearchIndex struct {
// contains filtered or unexported fields
}
SearchIndex builds and queries a searchable catalog of MCP tools.
func NewSearchIndex ¶
func NewSearchIndex(tools []Tool) *SearchIndex
NewSearchIndex creates a search index from the given tools.
func (*SearchIndex) Search ¶
func (idx *SearchIndex) Search(query string) []Tool
Search returns tools matching the query string. It searches tool names, descriptions, and parameter names. Results are returned with full schemas.
func (*SearchIndex) ToolCount ¶
func (idx *SearchIndex) ToolCount() int
ToolCount returns the number of indexed tools.
type ServerInfo ¶
ServerInfo contains information about the MCP server.
type Session ¶
type Session struct {
ID string
ClientInfo ClientInfo
Initialized bool
CreatedAt time.Time
LastSeen time.Time
}
Session represents an MCP client session.
type SessionManager ¶
type SessionManager struct {
// contains filtered or unexported fields
}
SessionManager manages client sessions.
func NewSessionManager ¶
func NewSessionManager() *SessionManager
NewSessionManager creates a new session manager.
func (*SessionManager) Cleanup ¶
func (m *SessionManager) Cleanup(maxAge time.Duration) int
Cleanup removes stale sessions older than the given duration.
func (*SessionManager) Count ¶
func (m *SessionManager) Count() int
Count returns the number of active sessions.
func (*SessionManager) Create ¶
func (m *SessionManager) Create(clientInfo ClientInfo) *Session
Create creates a new session. If the session count exceeds maxSessions, the oldest session (by LastSeen) is evicted.
func (*SessionManager) Delete ¶
func (m *SessionManager) Delete(id string)
Delete removes a session.
func (*SessionManager) Get ¶
func (m *SessionManager) Get(id string) *Session
Get retrieves a session by ID.
func (*SessionManager) Touch ¶
func (m *SessionManager) Touch(id string)
Touch updates the last seen time for a session.
type Spawner ¶
type Spawner interface {
Spawn(ctx context.Context) (AgentClient, error)
Reap(ctx context.Context, r *Replica) error
}
Spawner launches or reaps one replica for a named server. One implementation per transport class lives in pkg/controller. The Gateway constructs the right one at RegisterMCPReplicaSet time and hands it to NewAutoscaler.
Spawn MUST return a ready-to-serve AgentClient: Connect/Initialize/RefreshTools have completed before the returned value is added to the set, otherwise the first tool call routed to the new replica would fail. Reap is given the Replica (pre-removed from dispatch) and should close the underlying client and free any resources owned by the spawner.
type StdioClient ¶
type StdioClient struct {
RPCClient
// contains filtered or unexported fields
}
StdioClient communicates with an MCP server via container stdin/stdout.
func NewStdioClient ¶
func NewStdioClient(name, containerID string, cli dockerclient.DockerClient) *StdioClient
NewStdioClient creates a new stdio-based MCP client.
func (*StdioClient) Connect ¶
func (c *StdioClient) Connect(ctx context.Context) error
Connect attaches to the container's stdin/stdout.
func (*StdioClient) ContainerID ¶
func (c *StdioClient) ContainerID() string
ContainerID returns the docker container id this client was bound to.
func (*StdioClient) Ping ¶
func (c *StdioClient) Ping(ctx context.Context) error
Ping checks if the container stdio connection is alive by sending a JSON-RPC ping.
func (*StdioClient) Reconnect ¶
func (c *StdioClient) Reconnect(ctx context.Context) error
Reconnect closes the existing connection and re-establishes it, including the MCP handshake and tool refresh. Thread-safe: concurrent callers will block until reconnection completes.
func (*StdioClient) SetPingTimeout ¶
func (c *StdioClient) SetPingTimeout(d time.Duration)
SetPingTimeout overrides the per-ping deadline used by Ping. Zero restores the default (DefaultPingTimeout).
type StreamableHTTPServer ¶
type StreamableHTTPServer struct {
// contains filtered or unexported fields
}
StreamableHTTPServer implements the MCP Streamable HTTP transport (spec 2025-06-18). It handles POST, GET, and DELETE requests at a single /mcp endpoint.
func NewStreamableHTTPServer ¶
func NewStreamableHTTPServer(gateway *Gateway, allowedOrigins []string) *StreamableHTTPServer
NewStreamableHTTPServer creates a new Streamable HTTP server.
func (*StreamableHTTPServer) Close ¶
func (s *StreamableHTTPServer) Close()
Close tears down all active sessions and cancels their SSE streams.
func (*StreamableHTTPServer) ServeHTTP ¶
func (s *StreamableHTTPServer) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP routes /mcp requests based on HTTP method.
func (*StreamableHTTPServer) SessionCount ¶
func (s *StreamableHTTPServer) SessionCount() int
SessionCount returns the number of active Streamable HTTP sessions.
func (*StreamableHTTPServer) SessionIDs ¶
func (s *StreamableHTTPServer) SessionIDs() []string
SessionIDs returns the IDs of all active sessions.
func (*StreamableHTTPServer) SetAllowedOrigins ¶
func (s *StreamableHTTPServer) SetAllowedOrigins(origins []string)
SetAllowedOrigins updates the list of allowed origins for DNS rebinding protection.
type StreamableSession ¶
type StreamableSession struct {
ID string
// contains filtered or unexported fields
}
StreamableSession represents an active Streamable HTTP session.
type Tool ¶
type Tool struct {
Name string `json:"name"`
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
InputSchema json.RawMessage `json:"inputSchema"`
}
Tool represents an MCP tool definition.
func ExecuteTool ¶
func ExecuteTool() Tool
ExecuteTool returns the Tool definition for the execute meta-tool.
func SearchTool ¶
func SearchTool() Tool
SearchTool returns the Tool definition for the search meta-tool.
type ToolCallObserver ¶
type ToolCallObserver interface {
// ObserveToolCall is called after a tool call completes.
// serverName is the MCP server that handled the call.
// replicaID is the zero-indexed replica within that server's set, or -1
// when the caller did not dispatch through a ReplicaSet.
// arguments are the tool call arguments (input).
// result is the tool call response (output). May be nil on error.
ObserveToolCall(serverName string, replicaID int, arguments map[string]any, result *ToolCallResult)
}
ToolCallObserver receives notifications after tool calls complete. Used by the metrics system to count tokens without coupling the gateway to the metrics package directly.
type ToolCallParams ¶
type ToolCallParams struct {
Name string `json:"name"`
Arguments map[string]any `json:"arguments,omitempty"`
}
ToolCallParams contains parameters for tools/call.
type ToolCallResult ¶
type ToolCallResult struct {
Content []Content `json:"content"`
IsError bool `json:"isError,omitempty"`
}
ToolCallResult is the response to tools/call.
type ToolCaller ¶
type ToolCaller interface {
CallTool(ctx context.Context, name string, arguments map[string]any) (*ToolCallResult, error)
}
ToolCaller allows calling tools across the gateway's aggregated servers. This interface decouples the registry from the gateway to avoid circular dependencies. The gateway implements this interface and passes it to components that need to call tools without holding a direct reference to the gateway or router.
type ToolsCapability ¶
type ToolsCapability struct {
ListChanged bool `json:"listChanged,omitempty"`
}
ToolsCapability indicates tools support.
type ToolsListResult ¶
type ToolsListResult struct {
Tools []Tool `json:"tools"`
NextCursor *string `json:"nextCursor,omitempty"`
}
ToolsListResult is the response to tools/list.