Documentation
¶
Overview ¶
Package session provides per-session subprocess management for MCP servers.
Each upstream MCP session gets its own isolated subprocess connected via the go-sdk CommandTransport. The Manager tracks the mapping from session IDs to downstream ClientSessions and handles lifecycle (spawn, teardown, cleanup).
Index ¶
- Variables
- type Manager
- func (m *Manager) AdmissionStatus() (atCapacity bool, current int, max int)
- func (m *Manager) CloseAll()
- func (m *Manager) GetSession(sessionID string) *TrackedSession
- func (m *Manager) RemoveSession(sessionID string) error
- func (m *Manager) SessionCount() int
- func (m *Manager) Sessions() []string
- func (m *Manager) SetOnSessionRemoved(fn func(sessionID string))
- func (m *Manager) SpawnSession(ctx context.Context, sessionID string, clientOpts ...*mcp.ClientOptions) (*mcp.ClientSession, error)
- func (m *Manager) StartReaper(ctx context.Context, checkInterval time.Duration)
- func (m *Manager) TouchSession(sessionID string)
- type SharedSessionManager
- func (sm *SharedSessionManager) AdmissionStatus() (atCapacity bool, current int, max int)
- func (sm *SharedSessionManager) CloseAll()
- func (sm *SharedSessionManager) Downstream() *mcp.ClientSession
- func (sm *SharedSessionManager) GetOrCreateSession(ctx context.Context, sessionID string) (*mcp.ClientSession, error)
- func (sm *SharedSessionManager) HasDownstream() bool
- func (sm *SharedSessionManager) RefCount() int
- func (sm *SharedSessionManager) RemoveSession(sessionID string) error
- func (sm *SharedSessionManager) SessionCount() int
- func (sm *SharedSessionManager) StartHealthProbe(ctx context.Context)
- func (sm *SharedSessionManager) Subscribe(sessionID string, onRespawn func(*mcp.ClientSession))
- func (sm *SharedSessionManager) Unsubscribe(sessionID string)
- type TrackedSession
Constants ¶
This section is empty.
Variables ¶
var ( ErrSessionExists = errors.New("session: session already exists") ErrSessionNotFound = errors.New("session: session not found") ErrMaxSessions = errors.New("session: maximum concurrent sessions reached") )
Errors returned by session Manager operations.
Functions ¶
This section is empty.
Types ¶
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager manages per-session subprocess lifecycle for a single MCP server. Each upstream session gets its own subprocess, connected via CommandTransport.
func NewManager ¶
NewManager creates a new session Manager for the given server.
func (*Manager) AdmissionStatus ¶
AdmissionStatus returns current admission-control state. atCapacity is true only when MaxSessions is configured (>0) and reached.
func (*Manager) CloseAll ¶
func (m *Manager) CloseAll()
CloseAll terminates all sessions and their subprocesses.
func (*Manager) GetSession ¶
func (m *Manager) GetSession(sessionID string) *TrackedSession
GetSession returns the tracked session for the given session ID, or nil.
func (*Manager) RemoveSession ¶
RemoveSession terminates the downstream subprocess and removes the session. It gracefully closes the ClientSession (which closes stdin, waits, then SIGTERM/SIGKILL).
func (*Manager) SessionCount ¶
SessionCount returns the number of active sessions.
func (*Manager) SetOnSessionRemoved ¶
SetOnSessionRemoved registers a callback that fires before any session's downstream connection is closed. This is called from all removal paths: RemoveSession, reaper, and CloseAll. The callback receives the session ID and runs outside any Manager lock, allowing the proxy layer to gate further dispatches before the SDK connection is torn down.
func (*Manager) SpawnSession ¶
func (m *Manager) SpawnSession(ctx context.Context, sessionID string, clientOpts ...*mcp.ClientOptions) (*mcp.ClientSession, error)
SpawnSession creates a new downstream subprocess for the given session ID. It connects via CommandTransport, performs the initialize handshake, and returns the ready-to-use ClientSession. If clientOpts is non-nil, it is used to configure the downstream Client (e.g., for notification handlers).
func (*Manager) StartReaper ¶
StartReaper starts a background goroutine that periodically checks for idle and TTL-expired sessions and removes them. The reaper stops when the context is cancelled.
func (*Manager) TouchSession ¶
TouchSession updates the LastActivity timestamp for the given session. This should be called on each tool call or notification to keep the session alive.
type SharedSessionManager ¶
type SharedSessionManager struct {
// contains filtered or unexported fields
}
SharedSessionManager maintains a single downstream subprocess shared across all upstream sessions for stateless MCP servers.
func NewSharedSessionManager ¶
func NewSharedSessionManager(serverName string, cfg *config.ServerConfig, logger *slog.Logger, idleTimeout time.Duration, m metrics.ServerMetricsReporter) *SharedSessionManager
NewSharedSessionManager creates a new shared session manager. idleTimeout controls the idle reap behavior: when refCount drops to 0, the downstream subprocess is torn down after this duration. 0 disables idle reaping.
func (*SharedSessionManager) AdmissionStatus ¶
func (sm *SharedSessionManager) AdmissionStatus() (atCapacity bool, current int, max int)
AdmissionStatus returns current admission-control state.
func (*SharedSessionManager) CloseAll ¶
func (sm *SharedSessionManager) CloseAll()
CloseAll terminates the shared downstream subprocess and clears all state.
func (*SharedSessionManager) Downstream ¶
func (sm *SharedSessionManager) Downstream() *mcp.ClientSession
Downstream returns the current downstream session (may be nil).
func (*SharedSessionManager) GetOrCreateSession ¶
func (sm *SharedSessionManager) GetOrCreateSession(ctx context.Context, sessionID string) (*mcp.ClientSession, error)
GetOrCreateSession returns the shared downstream session, lazily spawning it on first use. The sessionID is tracked for admission control and refcounting.
func (*SharedSessionManager) HasDownstream ¶
func (sm *SharedSessionManager) HasDownstream() bool
HasDownstream reports whether a downstream session is currently active.
func (*SharedSessionManager) RefCount ¶
func (sm *SharedSessionManager) RefCount() int
RefCount returns the current upstream refcount.
func (*SharedSessionManager) RemoveSession ¶
func (sm *SharedSessionManager) RemoveSession(sessionID string) error
RemoveSession removes the upstream session from tracking and decrements refcount. If refCount reaches 0 and idle reap is enabled, starts the idle reap timer.
func (*SharedSessionManager) SessionCount ¶
func (sm *SharedSessionManager) SessionCount() int
SessionCount returns the number of tracked upstream sessions.
func (*SharedSessionManager) StartHealthProbe ¶
func (sm *SharedSessionManager) StartHealthProbe(ctx context.Context)
StartHealthProbe starts a background goroutine that periodically probes the shared downstream for liveness. If the probe fails, the downstream is respawned.
func (*SharedSessionManager) Subscribe ¶
func (sm *SharedSessionManager) Subscribe(sessionID string, onRespawn func(*mcp.ClientSession))
Subscribe registers a callback to be invoked when the downstream is respawned.
func (*SharedSessionManager) Unsubscribe ¶
func (sm *SharedSessionManager) Unsubscribe(sessionID string)
Unsubscribe removes the respawn callback for the given session ID.
type TrackedSession ¶
type TrackedSession struct {
SessionID string
Downstream *mcp.ClientSession
Client *mcp.Client
CreatedAt time.Time // When the session was spawned
LastActivity time.Time // Last time the session was actively used
}
TrackedSession holds the downstream client session and metadata for a single upstream MCP session.