Documentation
¶
Overview ¶
Package mcp provides HTTP handlers for MCP (Model Context Protocol) servers. Each MCP server runs on its own dedicated port, proxying requests to the underlying subprocess via the go-sdk StreamableHTTPHandler.
hardening.go provides HTTP server hardening for MCP Streamable HTTP endpoints.
Protections applied:
- Request body size limits (prevents DoS via large payloads)
- HTTP server timeouts (ReadTimeout, ReadHeaderTimeout, WriteTimeout, IdleTimeout)
- Per-listener rate limiting for /mcp endpoint (token-bucket)
proxy.go provides the per-session MCP proxy handler.
For each upstream MCP session, a new mcp.Server is created, a downstream subprocess is spawned via session.Manager, and tool handlers are registered that forward calls to the downstream ClientSession.
Routing modes:
- Fixed manager: ProxyConfig.SessionManager is set. Every upstream session spawns a downstream through that single manager. Used by single-server stdio proxies.
- Slot-group selector: ProxyConfig.Selector is set. On each new upstream session, the selector picks which underlying manager should own the session (least-loaded healthy slot). The chosen manager is stored on the resulting proxySession so pre-dispatch respawn stays on the same slot. Used by the virtual group listener built by the daemon for transparent multi-slot routing.
Exactly one of SessionManager or Selector must be set; NewProxyHandler panics otherwise.
Downstream-to-upstream notification relay:
- tools/list_changed: re-discovers tools from downstream and updates upstream server
- logging/message: relayed via ServerSession.Log()
- progress: relayed via ServerSession.NotifyProgress()
Lifecycle safety:
proxySession uses two separate locks: - mu: guards upstreamSession, upstreamSessionID, and currentTools - downstreamMu: guards downstream pointer and downstreamClosed flag Callers (tool handlers, notification relays) acquire downstreamMu.RLock to snapshot the downstream pointer and check the closed flag. closeDownstream acquires the write lock to set the flag and nil the pointer atomically before handing off to IO teardown. This prevents calls being dispatched after close has begun, eliminating the "client is closing" error surfacing to callers.
security.go provides HTTP security middleware for MCP Streamable HTTP endpoints.
The middleware enforces:
- Bearer token authentication (when configured)
- Strict Origin header allowlist (when configured)
- Rejection of wildcard CORS (Access-Control-Allow-Origin: * is never emitted)
- CORS preflight (OPTIONS) handling with proper headers
Security checks run in order: Origin → Auth. CORS preflight (OPTIONS) skips auth but still validates Origin.
Index ¶
- Constants
- Variables
- func ClassifyApplicationActivity(body []byte) (bool, error)
- func MaxBytesMiddleware(maxBytes int64) func(http.Handler) http.Handler
- func NewProxyHandler(cfg ProxyConfig) http.Handler
- func ProbeCompatibilityMiddleware(serverName string) func(http.Handler) http.Handler
- func ProbeManagedHTTPBackend(ctx context.Context, target *url.URL, transport http.RoundTripper) error
- func RateLimitMiddleware(burst int, interval time.Duration, logger ...*slog.Logger) func(http.Handler) http.Handler
- func SecurityMiddleware(cfg SecurityConfig) func(http.Handler) http.Handler
- type AdmissionStatuser
- type AvailabilityError
- type CircuitBreakerConfig
- type CircuitOpenError
- type DisconnectTracker
- type FailureCategory
- type FallbackSuggestion
- type FallbackSuggestionProvider
- type HardeningConfig
- type LeaseClock
- type LeaseManager
- func (m *LeaseManager) AggregateInFlight() int
- func (m *LeaseManager) BeginRequest(sessionID string, applicationActivity bool) (func(), error)
- func (m *LeaseManager) BeginSSE(sessionID string) error
- func (m *LeaseManager) CapacityUsed() int
- func (m *LeaseManager) Commit(res Reservation, sessionID string) error
- func (m *LeaseManager) EndSSE(sessionID string)
- func (m *LeaseManager) ExpireIdle() []string
- func (m *LeaseManager) FinalizeClose(sessionID string) bool
- func (m *LeaseManager) InFlight(sessionID string) int
- func (m *LeaseManager) InvalidateAll(reason ...string) int
- func (m *LeaseManager) MarkCleanupUncertain(sessionID, reason string) bool
- func (m *LeaseManager) ReleaseReservation(res Reservation)
- func (m *LeaseManager) Reserve() (Reservation, error)
- func (m *LeaseManager) RestoreActive(sessionID string) bool
- func (m *LeaseManager) Snapshot(limit int) LeaseSnapshot
- func (m *LeaseManager) TryBeginExpiry(sessionID, reason string) bool
- type LeaseSnapshot
- type LeaseSnapshotRow
- type LeaseState
- type ManagedBackendGate
- type ManagedGatewayMetrics
- type ManagedHTTPGateway
- func (g *ManagedHTTPGateway) CloseAll()
- func (g *ManagedHTTPGateway) InvalidateAll(reason string)
- func (g *ManagedHTTPGateway) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (g *ManagedHTTPGateway) Snapshot(limit int) LeaseSnapshot
- func (g *ManagedHTTPGateway) StartReaper(ctx context.Context, interval time.Duration)
- type ManagedHTTPGatewayConfig
- type ManagerSelector
- type PortManager
- func (pm *PortManager) AddStreamable(name string, port int, handler http.Handler, sessionMgr SessionCloser, ...) error
- func (pm *PortManager) AddStreamableWithHardening(name string, port int, handler http.Handler, sessionMgr SessionCloser, ...) error
- func (pm *PortManager) Close() error
- func (pm *PortManager) Get(name string) *ServerListener
- func (pm *PortManager) List() []*ServerListener
- func (pm *PortManager) Remove(name string) error
- type PortManagerError
- type ProxyConfig
- type Reservation
- type RetryConfig
- type SecurityConfig
- type ServerListener
- type SessionCloser
Constants ¶
const ( // DefaultMaxBodyBytes is the maximum request body size for MCP endpoints (4 MB). // MCP JSON-RPC messages are typically small (< 100 KB). 4 MB provides // headroom for tool arguments with embedded data while preventing abuse. DefaultMaxBodyBytes int64 = 4 * 1024 * 1024 // DefaultReadTimeout is the max duration for reading the entire request (header + body). DefaultReadTimeout = 30 * time.Second // DefaultReadHeaderTimeout is the max duration for reading request headers. DefaultReadHeaderTimeout = 10 * time.Second // DefaultWriteTimeout is the max duration for writing the response. // Set to 0 (unlimited) because SSE streams must stay open indefinitely. DefaultWriteTimeout = 0 // DefaultIdleTimeout is the max duration an idle keep-alive connection is kept open. DefaultIdleTimeout = 120 * time.Second // DefaultRateBurst is the max burst of requests allowed through the rate limiter. DefaultRateBurst = 50 // DefaultRateInterval is the refill interval for the rate limiter bucket. // One token per interval, so 50 burst / 50ms refill = ~1000 req/s sustained. DefaultRateInterval = 50 * time.Millisecond )
Variables ¶
var ( ErrServerAlreadyRegistered = &PortManagerError{"server already registered"} ErrServerNotRegistered = &PortManagerError{"server not registered"} )
Errors
var ( ErrLeaseCapacity = errors.New("mcp lease capacity reached") ErrLeaseNotActive = errors.New("mcp lease is not active") ErrReservationNotFound = errors.New("mcp lease reservation not found") ErrLeaseExists = errors.New("mcp lease already exists") )
ErrDownstreamUnavailable is returned when a tool call or notification relay is attempted after the downstream session has been closed.
Functions ¶
func ClassifyApplicationActivity ¶ added in v1.3.3
ClassifyApplicationActivity returns true only when a JSON-RPC envelope contains a client request that is not protocol-maintenance ping traffic.
func MaxBytesMiddleware ¶
MaxBytesMiddleware wraps a handler to enforce a request body size limit. Requests exceeding the limit receive 413 Request Entity Too Large.
func NewProxyHandler ¶
func NewProxyHandler(cfg ProxyConfig) http.Handler
NewProxyHandler creates a StreamableHTTPHandler that proxies MCP requests to per-session downstream subprocesses.
For each new upstream session:
- A new mcp.Server is created (with HasTools: true)
- A downstream subprocess is spawned via SessionManager.SpawnSession()
- Tools are discovered from the downstream and registered as proxy handlers
- The server is returned to handle the session
- Notifications from downstream are relayed to the upstream client
func ProbeCompatibilityMiddleware ¶
ProbeCompatibilityMiddleware returns a short-lived legacy SSE handshake for GET /mcp requests that do not yet carry an Mcp-Session-Id.
This preserves normal MCP session semantics for real clients while improving interoperability with older tooling that still probes MCP endpoints with the pre-streamable SSE transport.
func ProbeManagedHTTPBackend ¶ added in v1.3.3
func ProbeManagedHTTPBackend(ctx context.Context, target *url.URL, transport http.RoundTripper) error
ProbeManagedHTTPBackend verifies native MCP readiness with one bounded initialize/delete pair. It never retries either request. Callers must recycle the backend before another probe when this function returns after initialize may have reached the server.
func RateLimitMiddleware ¶
func RateLimitMiddleware(burst int, interval time.Duration, logger ...*slog.Logger) func(http.Handler) http.Handler
RateLimitMiddleware wraps a handler with a token-bucket rate limiter. Requests exceeding the rate receive 429 Too Many Requests. An optional logger can be provided to log rate limit denials.
func SecurityMiddleware ¶
func SecurityMiddleware(cfg SecurityConfig) func(http.Handler) http.Handler
SecurityMiddleware returns an HTTP middleware that enforces bearer auth and Origin allowlist on MCP endpoints.
Evaluation order:
- Origin check (if AllowedOrigins configured and request has Origin header)
- CORS preflight response (OPTIONS requests skip auth)
- Bearer auth check (if BearerToken configured)
- Pass to inner handler
Types ¶
type AdmissionStatuser ¶
AdmissionStatuser abstracts admission-control state for fixed and multiplexed session managers.
type AvailabilityError ¶
type AvailabilityError struct {
Category FailureCategory
Err error
}
AvailabilityError exposes an operational failure category while retaining the original underlying error for callers that need to inspect or unwrap it.
func (*AvailabilityError) Error ¶
func (e *AvailabilityError) Error() string
func (*AvailabilityError) Unwrap ¶
func (e *AvailabilityError) Unwrap() error
type CircuitBreakerConfig ¶
CircuitBreakerConfig controls fast-fail behavior after repeated failures.
type CircuitOpenError ¶
CircuitOpenError reports that the downstream circuit is open and currently fast-failing.
func (*CircuitOpenError) Error ¶
func (e *CircuitOpenError) Error() string
type DisconnectTracker ¶ added in v1.2.3
type DisconnectTracker struct {
// contains filtered or unexported fields
}
DisconnectTracker tracks active HTTP connections per upstream MCP session ID and triggers deferred session cleanup after a configurable grace period when all connections for a session close.
Only used for shared-mode servers. All refcount and timer operations are serialized under a single mutex to eliminate TOCTOU races.
func (*DisconnectTracker) HandleDelete ¶ added in v1.2.3
func (dt *DisconnectTracker) HandleDelete(sessionID string)
HandleDelete cancels any pending grace timer for a session and removes it from tracking. Called when DELETE arrives for a session.
func (*DisconnectTracker) Stop ¶ added in v1.2.3
func (dt *DisconnectTracker) Stop()
Stop cancels all pending grace timers and prevents new tracking.
type FailureCategory ¶
type FailureCategory string
const ( FailureCategoryConfigDrift FailureCategory = "config_drift" FailureCategoryProviderTimeout FailureCategory = "provider_timeout" FailureCategoryRetryExhausted FailureCategory = "retry_exhausted" FailureCategoryCircuitOpen FailureCategory = "circuit_open" )
type FallbackSuggestion ¶ added in v1.2.2
type FallbackSuggestion struct {
ServerName string
Capabilities []string
Installed bool
Source string
Reason string
}
FallbackSuggestion describes one alternative server that may satisfy the same capability as a failed tool call. It is advisory only; Vision never invokes suggested alternatives automatically.
type FallbackSuggestionProvider ¶ added in v1.2.2
type FallbackSuggestionProvider interface {
SuggestAlternatives(ctx context.Context, failedServer, failedTool string) []FallbackSuggestion
}
FallbackSuggestionProvider supplies alternative MCP servers for a failed tool call. Implementations should be side-effect free; callers decide whether to use any returned suggestion.
type HardeningConfig ¶
type HardeningConfig struct {
// MaxBodyBytes caps the request body size. 0 uses DefaultMaxBodyBytes.
MaxBodyBytes int64
// ReadTimeout for http.Server. 0 uses DefaultReadTimeout.
ReadTimeout time.Duration
// ReadHeaderTimeout for http.Server. 0 uses DefaultReadHeaderTimeout.
ReadHeaderTimeout time.Duration
// WriteTimeout for http.Server. Negative disables (0 = SSE-safe default = no timeout).
WriteTimeout time.Duration
// IdleTimeout for http.Server. 0 uses DefaultIdleTimeout.
IdleTimeout time.Duration
// RateBurst is the token bucket burst size. 0 uses DefaultRateBurst.
// Set to -1 to disable rate limiting.
RateBurst int
// RateInterval is the token refill interval. 0 uses DefaultRateInterval.
RateInterval time.Duration
}
HardeningConfig holds hardening settings. Zero values use defaults.
func (HardeningConfig) ApplyServerTimeouts ¶
func (h HardeningConfig) ApplyServerTimeouts(srv *http.Server)
ApplyServerTimeouts applies hardening timeouts to an http.Server.
type LeaseClock ¶ added in v1.3.3
LeaseClock makes lease expiry deterministic in tests.
type LeaseManager ¶ added in v1.3.3
type LeaseManager struct {
// contains filtered or unexported fields
}
LeaseManager is the sole mutation authority for managed HTTP admission and per-session lifecycle state.
func NewLeaseManager ¶ added in v1.3.3
func NewLeaseManager(maxSessions int, idleTimeout time.Duration, clock LeaseClock) *LeaseManager
func (*LeaseManager) AggregateInFlight ¶ added in v1.3.3
func (m *LeaseManager) AggregateInFlight() int
func (*LeaseManager) BeginRequest ¶ added in v1.3.3
func (m *LeaseManager) BeginRequest(sessionID string, applicationActivity bool) (func(), error)
BeginRequest atomically admits an active session request and returns an idempotent completion guard. Only structurally classified application requests refresh lastActivity.
func (*LeaseManager) BeginSSE ¶ added in v1.3.3
func (m *LeaseManager) BeginSSE(sessionID string) error
func (*LeaseManager) CapacityUsed ¶ added in v1.3.3
func (m *LeaseManager) CapacityUsed() int
func (*LeaseManager) Commit ¶ added in v1.3.3
func (m *LeaseManager) Commit(res Reservation, sessionID string) error
func (*LeaseManager) EndSSE ¶ added in v1.3.3
func (m *LeaseManager) EndSSE(sessionID string)
func (*LeaseManager) ExpireIdle ¶ added in v1.3.3
func (m *LeaseManager) ExpireIdle() []string
ExpireIdle atomically transitions eligible leases to expiring. Cleanup IO happens outside the manager; FinalizeClose releases capacity after proof.
func (*LeaseManager) FinalizeClose ¶ added in v1.3.3
func (m *LeaseManager) FinalizeClose(sessionID string) bool
func (*LeaseManager) InFlight ¶ added in v1.3.3
func (m *LeaseManager) InFlight(sessionID string) int
func (*LeaseManager) InvalidateAll ¶ added in v1.3.3
func (m *LeaseManager) InvalidateAll(reason ...string) int
InvalidateAll clears every lease and pending reservation after the owning backend process or public listener has been torn down. No downstream session can remain reachable after that ownership boundary disappears.
func (*LeaseManager) MarkCleanupUncertain ¶ added in v1.3.3
func (m *LeaseManager) MarkCleanupUncertain(sessionID, reason string) bool
func (*LeaseManager) ReleaseReservation ¶ added in v1.3.3
func (m *LeaseManager) ReleaseReservation(res Reservation)
func (*LeaseManager) Reserve ¶ added in v1.3.3
func (m *LeaseManager) Reserve() (Reservation, error)
func (*LeaseManager) RestoreActive ¶ added in v1.3.3
func (m *LeaseManager) RestoreActive(sessionID string) bool
RestoreActive reverses an expiry transition only when no cleanup request was dispatched. It is used for pre-dispatch backend admission failures.
func (*LeaseManager) Snapshot ¶ added in v1.3.3
func (m *LeaseManager) Snapshot(limit int) LeaseSnapshot
func (*LeaseManager) TryBeginExpiry ¶ added in v1.3.3
func (m *LeaseManager) TryBeginExpiry(sessionID, reason string) bool
type LeaseSnapshot ¶ added in v1.3.3
type LeaseSnapshot struct {
CapacityUsed int
CapacityMax int
Rows []LeaseSnapshotRow
Omitted int
Closed []LeaseSnapshotRow
ClosedOmitted int
}
type LeaseSnapshotRow ¶ added in v1.3.3
type LeaseState ¶ added in v1.3.3
type LeaseState string
const ( LeaseStateActive LeaseState = "active" LeaseStateExpiring LeaseState = "expiring" LeaseStateCleanupUncertain LeaseState = "cleanup_uncertain" LeaseStateClosed LeaseState = "closed" )
type ManagedBackendGate ¶ added in v1.3.3
ManagedBackendGate blocks dispatch while the supervised native HTTP backend is starting, draining, or restarting.
type ManagedGatewayMetrics ¶ added in v1.3.3
type ManagedGatewayMetrics interface {
IncActiveSessions()
DecActiveSessions()
IncAdmissionDenied()
IncReaped(reason string)
}
type ManagedHTTPGateway ¶ added in v1.3.3
type ManagedHTTPGateway struct {
// contains filtered or unexported fields
}
ManagedHTTPGateway is the lifecycle-aware boundary between Vision's public MCP listener and one loopback-only native Streamable HTTP MCP backend. It preserves backend-generated session IDs and forwards every request at most once.
func NewManagedHTTPGateway ¶ added in v1.3.3
func NewManagedHTTPGateway(cfg ManagedHTTPGatewayConfig) (*ManagedHTTPGateway, error)
func (*ManagedHTTPGateway) CloseAll ¶ added in v1.3.3
func (g *ManagedHTTPGateway) CloseAll()
CloseAll implements SessionCloser. Listener teardown coincides with backend process teardown, so all in-memory claims can be invalidated without sending synthetic DELETE requests.
func (*ManagedHTTPGateway) InvalidateAll ¶ added in v1.3.3
func (g *ManagedHTTPGateway) InvalidateAll(reason string)
func (*ManagedHTTPGateway) ServeHTTP ¶ added in v1.3.3
func (g *ManagedHTTPGateway) ServeHTTP(w http.ResponseWriter, r *http.Request)
func (*ManagedHTTPGateway) Snapshot ¶ added in v1.3.3
func (g *ManagedHTTPGateway) Snapshot(limit int) LeaseSnapshot
func (*ManagedHTTPGateway) StartReaper ¶ added in v1.3.3
func (g *ManagedHTTPGateway) StartReaper(ctx context.Context, interval time.Duration)
type ManagedHTTPGatewayConfig ¶ added in v1.3.3
type ManagedHTTPGatewayConfig struct {
Target *url.URL
MaxSessions int
IdleTimeout time.Duration
Clock LeaseClock
Transport http.RoundTripper
Backend ManagedBackendGate
OnAmbiguousFailure func(error)
Metrics ManagedGatewayMetrics
Logger *slog.Logger
}
type ManagerSelector ¶
type ManagerSelector interface {
SessionCloser
AdmissionStatuser
SelectForNewSession(ctx context.Context, upstreamSessionID string) (*session.Manager, error)
Rebind(oldKey, newKey string)
ReportSpawnResult(sessionKey string, err error)
SetOnSessionRemoved(fn func(sessionID string))
Release(upstreamSessionID string)
}
ManagerSelector chooses which concrete session manager should own a new upstream session. Used by slot groups for transparent routing.
type PortManager ¶
type PortManager struct {
// contains filtered or unexported fields
}
PortManager manages HTTP listeners for MCP servers. Each server gets its own dedicated port.
func NewPortManager ¶
func NewPortManager(logger *slog.Logger) *PortManager
NewPortManager creates a new port manager.
func (*PortManager) AddStreamable ¶
func (pm *PortManager) AddStreamable(name string, port int, handler http.Handler, sessionMgr SessionCloser, security ...SecurityConfig) error
AddStreamable registers and starts an HTTP listener backed by a StreamableHTTPHandler. The handler serves the MCP endpoint; sessionMgr (if non-nil) is closed when the listener is removed. If security is non-nil, the SecurityMiddleware is applied to the MCP handler. Default hardening (timeouts, body size cap, rate limiting) is always applied.
func (*PortManager) AddStreamableWithHardening ¶
func (pm *PortManager) AddStreamableWithHardening(name string, port int, handler http.Handler, sessionMgr SessionCloser, hardening HardeningConfig, security ...SecurityConfig) error
AddStreamableWithHardening registers and starts a hardened HTTP listener with custom hardening config. This allows overriding default timeouts, body size limits, and rate limiting.
func (*PortManager) Close ¶
func (pm *PortManager) Close() error
Close shuts down all listeners, closes session managers, and waits for goroutines to exit.
func (*PortManager) Get ¶
func (pm *PortManager) Get(name string) *ServerListener
Get returns the listener for a server.
func (*PortManager) List ¶
func (pm *PortManager) List() []*ServerListener
List returns all active listeners.
func (*PortManager) Remove ¶
func (pm *PortManager) Remove(name string) error
Remove stops and removes the listener for a server. If the listener has a SessionManager, all sessions are closed first.
type PortManagerError ¶
type PortManagerError struct {
Message string
}
PortManagerError is an error from the port manager.
func (*PortManagerError) Error ¶
func (e *PortManagerError) Error() string
type ProxyConfig ¶
type ProxyConfig struct {
// ServerName is the name of the MCP server being proxied.
ServerName string
// SessionManager manages downstream subprocess lifecycle.
SessionManager *session.Manager
// Selector chooses which session manager should own a new upstream session.
// Used by slot groups for transparent routing. When nil, SessionManager is
// used directly.
Selector ManagerSelector
// upstream sessions for stateless MCP servers. When set, SessionManager and
// Selector must both be nil.
SharedManager *session.SharedSessionManager
// Logger for proxy operations.
Logger *slog.Logger
// SuggestionProvider supplies alternative tool suggestions when downstream
// availability failures are returned to the upstream client as tool results.
SuggestionProvider FallbackSuggestionProvider
// HealthCheckInterval is how often to probe idle downstream sessions.
// 0 means no proactive health checking (reactive respawn only).
HealthCheckInterval time.Duration
// RequestTimeout is the default downstream tool-call deadline when the
// upstream request has no earlier deadline.
RequestTimeout time.Duration
// RetryConfig controls retry behavior for retryable downstream failures.
RetryConfig RetryConfig
// CircuitBreakerConfig controls fast-fail behavior after repeated failures.
CircuitBreakerConfig CircuitBreakerConfig
// concurrent sessions for this server.
SharedReadOnlyTools []string
// stay cached. 0 disables caching while still allowing in-flight coalescing.
SharedResultCacheTTL time.Duration
// 0 uses the default size.
SharedResultCacheSize int
// MaxInFlightRequests caps concurrent downstream tool calls per server.
// 0 means unlimited.
MaxInFlightRequests int
// DisconnectGracePeriod is the time to wait after the last HTTP connection
// closes before removing a shared-mode upstream session. 0 disables disconnect
// detection. Set from ServerConfig.ResolvedDisconnectGracePeriod().
DisconnectGracePeriod time.Duration
// Metrics tracks per-server session lifecycle counters. Optional; nil = no metrics.
Metrics metrics.ServerMetricsReporter
}
ProxyConfig configures a per-session proxy handler.
type Reservation ¶ added in v1.3.3
type Reservation struct {
// contains filtered or unexported fields
}
Reservation is an opaque capacity claim created before a downstream server returns its session identifier.
type RetryConfig ¶
type RetryConfig struct {
MaxAttempts int
InitialDelay time.Duration
MaxDelay time.Duration
RetryableErrors []string
}
RetryConfig controls retry behavior for retryable downstream failures.
type SecurityConfig ¶
type SecurityConfig struct {
// BearerToken is the expected bearer token for Authorization header validation.
// When empty, authentication is not enforced (open access).
BearerToken string
// AllowedOrigins is the list of permitted Origin header values.
// When empty, origin checking is not enforced.
// Wildcard ("*") entries are explicitly rejected and treated as if origin is disallowed.
AllowedOrigins []string
// Logger for security events. When nil, security events are not logged.
Logger *slog.Logger
}
SecurityConfig holds security settings for MCP endpoints. All fields are optional — when zero-valued, the corresponding check is skipped.
type ServerListener ¶
type ServerListener struct {
Name string
Port int
MCPHandler http.Handler // Streamable HTTP handler
SessionManager SessionCloser // Session manager for cleanup (nil if not applicable)
Server *http.Server
}
ServerListener holds the HTTP server for a single MCP server.
type SessionCloser ¶
type SessionCloser interface {
CloseAll()
}
SessionCloser is implemented by types that manage per-session resources and need cleanup when a server listener is removed.