Documentation
¶
Overview ¶
Package session provides vMCP-specific session types that extend transport sessions with domain logic.
Index ¶
Constants ¶
const ( // MetadataKeyIdentitySubject is the transport-session metadata key that // holds the subject claim of the authenticated caller (identity.Subject). // Set at session creation; empty for anonymous callers. MetadataKeyIdentitySubject = "vmcp.identity.subject" // MetadataKeyBackendIDs is the transport-session metadata key that holds // a comma-separated, sorted list of successfully-connected backend IDs. // The key is omitted entirely when no backends connected. MetadataKeyBackendIDs = "vmcp.backend.ids" )
Variables ¶
var ( // ErrSessionClosed is returned when an operation is attempted on a closed session. ErrSessionClosed = errors.New("session is closed") // ErrToolNotFound is returned when the requested tool is not in the routing table. ErrToolNotFound = errors.New("tool not found in session routing table") // ErrResourceNotFound is returned when the requested resource is not in the routing table. ErrResourceNotFound = errors.New("resource not found in session routing table") // ErrPromptNotFound is returned when the requested prompt is not in the routing table. ErrPromptNotFound = errors.New("prompt not found in session routing table") // ErrNoBackendClient is returned when the routing table references a backend // that has no entry in the connections map. This indicates an internal // invariant violation: under normal operation MakeSession always populates // both maps together, so this error should never be seen at runtime. ErrNoBackendClient = errors.New("no client available for backend") )
Sentinel errors returned by defaultMultiSession methods.
Functions ¶
func VMCPSessionFactory ¶
func VMCPSessionFactory() transportsession.Factory
VMCPSessionFactory creates a factory function for the session manager.
Types ¶
type AdmissionQueue ¶ added in v0.10.1
type AdmissionQueue interface {
// TryAdmit attempts to admit a request. If the queue is open, it returns
// (true, done) where done must be called when the request completes.
// If the queue is already closed, it returns (false, nil).
TryAdmit() (bool, func())
// CloseAndDrain closes the queue so that subsequent TryAdmit calls return
// false, then blocks until all currently-admitted requests have called
// their done function. Idempotent.
CloseAndDrain()
}
AdmissionQueue controls admission of concurrent requests to a shared resource that can be closed. Once closed, no further requests are admitted and CloseAndDrain blocks until all previously-admitted requests complete.
type MultiSession ¶ added in v0.10.1
type MultiSession interface {
transportsession.Session
sessiontypes.Caller
// Tools returns the resolved tools available in this session.
// The list is built once at session creation and is read-only thereafter.
Tools() []vmcp.Tool
// Resources returns the resolved resources available in this session.
Resources() []vmcp.Resource
// Prompts returns the resolved prompts available in this session.
Prompts() []vmcp.Prompt
// BackendSessions returns a snapshot of the backend-assigned session IDs,
// keyed by backend workload ID. The backend session ID is assigned by the
// backend MCP server and is used to correlate vMCP sessions with backend
// sessions for debugging and auditing.
BackendSessions() map[string]string
}
MultiSession is the vMCP domain session interface. It extends the transport-layer Session with behaviour: capability access and session-scoped backend routing across multiple backend connections.
A MultiSession is a "session of sessions": each backend contributes its own persistent connection (see backend.Session in pkg/vmcp/session/internal/backend), and the MultiSession aggregates them behind a single routing table.
Distributed deployment note ¶
Because MCP clients cannot be serialised, horizontal scaling requires sticky sessions (session affinity at the load balancer). Without sticky sessions, a request routed to a different vMCP instance must recreate backend clients (one-time cost per re-route). This is an accepted trade-off.
Storage ¶
A MultiSession uses a two-layer storage model:
Runtime layer (in-process only): backend HTTP connections, routing table, and capability lists. These cannot be serialized and are lost when the process exits. Sessions are therefore node-local.
Metadata layer (serializable): identity subject and connected backend IDs are written to the embedded transportsession.Session so that pluggable transportsession.Storage backends (e.g. Redis) can persist them. This enables auditing and future session reconstruction, but does not make the session itself portable — the runtime layer must be rebuilt from scratch on a different node.
type MultiSessionFactory ¶ added in v0.10.1
type MultiSessionFactory interface {
// MakeSession creates a new MultiSession for the given identity against the
// provided set of backends. Backend clients are initialised in parallel
// with bounded concurrency (see WithMaxBackendInitConcurrency).
//
// Partial initialisation: if a backend fails to initialise, a warning is
// logged and the session continues with the remaining backends. The caller
// receives a valid session as long as at least one backend succeeded.
//
// If all backends fail, MakeSession still returns a valid (empty) session
// rather than an error, allowing clients to connect even when all backends
// are temporarily unavailable.
//
// TODO(sessionManagementV2): MakeSession is only used by tests for convenience
// (auto-generates UUID). Production code uses MakeSessionWithID exclusively.
// This method can be removed once the sessionManagementV2 migration is complete
// and VMCPSession is deleted. Tests can be updated to generate their own UUIDs.
MakeSession(ctx context.Context, identity *auth.Identity, backends []*vmcp.Backend) (MultiSession, error)
// MakeSessionWithID creates a new MultiSession with a specific session ID.
// This is used by SessionManager to create sessions using the SDK-assigned ID
// rather than generating a new UUID internally.
//
// The id parameter must be non-empty and should be a valid MCP session ID
// (visible ASCII characters, 0x21 to 0x7E per the MCP specification).
//
// All other behaviour (partial initialisation, bounded concurrency, etc.)
// is identical to MakeSession.
MakeSessionWithID(ctx context.Context, id string, identity *auth.Identity, backends []*vmcp.Backend) (MultiSession, error)
}
MultiSessionFactory creates new MultiSessions for connecting clients.
func NewSessionFactory ¶ added in v0.10.1
func NewSessionFactory(registry vmcpauth.OutgoingAuthRegistry, opts ...MultiSessionFactoryOption) MultiSessionFactory
NewSessionFactory creates a MultiSessionFactory that connects to backends over HTTP using the given outgoing auth registry.
type MultiSessionFactoryOption ¶ added in v0.10.1
type MultiSessionFactoryOption func(*defaultMultiSessionFactory)
MultiSessionFactoryOption configures a defaultMultiSessionFactory.
func WithBackendInitTimeout ¶ added in v0.10.1
func WithBackendInitTimeout(d time.Duration) MultiSessionFactoryOption
WithBackendInitTimeout sets the per-backend timeout during MakeSession. Defaults to 30 s.
func WithMaxBackendInitConcurrency ¶ added in v0.10.1
func WithMaxBackendInitConcurrency(n int) MultiSessionFactoryOption
WithMaxBackendInitConcurrency sets the maximum number of backends that are initialised concurrently during MakeSession. Defaults to 10.
type VMCPSession ¶
type VMCPSession struct {
*transportsession.StreamableSession
// contains filtered or unexported fields
}
VMCPSession extends StreamableSession with domain-specific routing data. This keeps routing table state in the application layer (pkg/vmcp/server) rather than polluting the transport layer (pkg/transport/session) with domain concerns.
Design Rationale:
- Embeds StreamableSession to inherit Session interface and streamable HTTP behavior
- Adds routing table for per-session capability routing
- Stores tool list with InputSchema for type coercion in composite tool workflows
- Maintains lifecycle synchronization with underlying transport session
- Provides type-safe access to routing table (vs. interface{} casting)
Lifecycle:
- Created by VMCPSessionFactory during sessionIDAdapter.Generate()
- Routing table and tools populated in AfterInitialize hook
- Retrieved by middleware on subsequent requests via type assertion
- Cleaned up automatically by session.Manager TTL worker
TODO: VMCPSession is a transitional type. Once the server layer is wired to use MultiSession (see SessionManagementV2), VMCPSession will be removed.
func GetVMCPSession ¶
func GetVMCPSession(sessionID string, mgr *transportsession.Manager) (*VMCPSession, error)
GetVMCPSession retrieves and validates a VMCPSession from the session manager.
This helper abstracts the common pattern of:
- Retrieving a session from the manager
- Type-asserting to *VMCPSession
- Handling errors with clear messages
func NewVMCPSession ¶
func NewVMCPSession(id string) *VMCPSession
NewVMCPSession creates a VMCPSession with initialized StreamableSession. The routing table is initially nil and will be populated during AfterInitialize hook.
This function panics if NewStreamableSession returns an unexpected type. This is intentional fail-fast behavior for programming errors that should be caught during development/testing. The type assertion should always succeed since NewStreamableSession is under our control and always returns *StreamableSession. A panic here indicates a bug in the transport layer that needs to be fixed, not a runtime condition to handle gracefully.
func (*VMCPSession) GetRoutingTable ¶
func (s *VMCPSession) GetRoutingTable() *vmcp.RoutingTable
GetRoutingTable retrieves the routing table for this session. Returns nil if capabilities have not been initialized yet.
func (*VMCPSession) GetTools ¶ added in v0.6.17
func (s *VMCPSession) GetTools() []vmcp.Tool
GetTools retrieves the tools list for this session. Returns nil if capabilities have not been initialized yet.
func (*VMCPSession) SetRoutingTable ¶
func (s *VMCPSession) SetRoutingTable(rt *vmcp.RoutingTable)
SetRoutingTable sets the routing table for this session. Called during AfterInitialize hook after capability discovery.
func (*VMCPSession) SetTools ¶ added in v0.6.17
func (s *VMCPSession) SetTools(tools []vmcp.Tool)
SetTools sets the tools list for this session. Called during AfterInitialize hook after capability discovery. The tools list includes InputSchema needed for type coercion in composite tool workflows.
func (*VMCPSession) Type ¶
func (*VMCPSession) Type() transportsession.SessionType
Type identifies this as a streamable vMCP session.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
internal
|
|
|
backend
Package backend defines the Session interface for a single persistent backend connection and provides the HTTP-based implementation used in production.
|
Package backend defines the Session interface for a single persistent backend connection and provides the HTTP-based implementation used in production. |
|
Package types defines shared session interfaces for the vmcp/session package hierarchy.
|
Package types defines shared session interfaces for the vmcp/session package hierarchy. |