Skip to content

RFC: Session-Scoped Architecture for vMCP#38

Merged
yrobla merged 8 commits intomainfrom
session-scoped-mcp-client
Feb 18, 2026
Merged

RFC: Session-Scoped Architecture for vMCP#38
yrobla merged 8 commits intomainfrom
session-scoped-mcp-client

Conversation

@yrobla
Copy link
Contributor

@yrobla yrobla commented Feb 4, 2026

RFC: Session-Scoped Architecture for vMCP

This RFC refactors vMCP session management to fix per-request client creation and scattered session concerns.

Problem

  • Per-request overhead: Backend clients created/closed on every tool call, causing connection overhead and state loss for stateful
    backends (Playwright, databases)
  • Scattered architecture: Session creation tangled across middleware, adapters, and SDK hooks with no clear ownership
  • Hard to extend: Current design makes it difficult to add features (optimizer-in-vmcp) or write integration tests without spinning up
    the full server

Solution

Introduce two core interfaces:

  1. Session - Domain object that owns backend clients, encapsulates routing logic, manages lifecycle
  2. SessionFactory - Creates fully-formed sessions (capability discovery + client initialization)
  3. SessionManager - Bridges domain logic to SDK protocol concerns

Key improvement: Clients created once during session init, reused for all requests, closed on expiration.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an RFC proposing a shift from per-request/lazy MCP backend client creation to session-scoped client lifecycle management to simplify the current pooling approach while preserving backend state across tool calls.

Changes:

  • Introduces a new RFC describing a session-scoped backend client map owned by VMCPSession.
  • Specifies eager client initialization during session setup (AfterInitialize) and cleanup during session close.
  • Outlines phased implementation steps, testing strategy, and alternatives considered.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@yrobla yrobla force-pushed the session-scoped-mcp-client branch from f935166 to 6e503d4 Compare February 4, 2026 13:40
The RFC captures the complete architectural vision from the discussion,
providing a roadmap for simplifying the client pooling implementation
while maintaining all current functionality.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@yrobla yrobla force-pushed the session-scoped-mcp-client branch 3 times, most recently from 840b512 to ddf4273 Compare February 4, 2026 15:26
@yrobla yrobla requested a review from Copilot February 4, 2026 15:26
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@yrobla yrobla force-pushed the session-scoped-mcp-client branch 2 times, most recently from 50f4742 to ec70d08 Compare February 4, 2026 15:51
@yrobla yrobla requested a review from Copilot February 4, 2026 15:52
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@yrobla yrobla force-pushed the session-scoped-mcp-client branch 2 times, most recently from 54dd1b4 to d714819 Compare February 4, 2026 16:28
Copy link

@jerm-dro jerm-dro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left two bigger comments elaborating on my thoughts. To summarize, I think there are larger problems with how the session concept is handled within vMCP. Namely, we have session concerns scattered throughout the codebase and all of these concerns are tightly coupled. As a solution, I think we should create an interface that encapsulates these concerns:

// Session represents an active MCP session with all its capabilities and resources.
// This is a pure domain object - no protocol concerns and can be run without being spun up in a server.
type Session interface {
    ID() string

    // Capabilities - returns discovered tools/resources for this session
    // Perhaps these could be combined into one "GetCapabilities" method.
    Tools() []Tool
    Resources() []Resource

    // MCP operations - routing logic is encapsulated here
    CallTool(ctx context.Context, name string, arguments map[string]any) (*ToolResult, error)
    ReadResource(ctx context.Context, uri string) (*ResourceResult, error)
    GetPrompt(ctx context.Context, name string, arguments map[string]any) (*PromptResult, error)

    // Lifecycle
    Close() error
}

That would make solving this client-lifetime problem trivial.

yrobla added a commit that referenced this pull request Feb 9, 2026
Address architectural feedback from PR #38 review, specifically jerm-dro's
comments about the root cause being scattered session concerns rather than
just client lifecycle management.

Major changes:

1. **Expanded Problem Statement**:
   - Identified root cause: session concerns scattered across middleware,
     adapters, and hooks
   - Current VMCPSession is a passive data container, not a domain object
   - Session construction tangled with SDK lifecycle callbacks
   - Hard to create session-scoped resources (clients, optimizer features)

2. **Introduced Core Interfaces**:
   - Session interface: Domain object that owns clients, encapsulates routing,
     manages lifecycle (not just a data container)
   - SessionFactory interface: Creates fully-formed sessions with all
     dependencies (discovery, client init, routing setup)
   - SessionManager: Bridges between domain (Session) and protocol (SDK)

3. **Updated Goals**:
   - Primary goal: Encapsulate session behavior in clean interfaces
   - Decouple session creation from SDK wiring
   - Enable testing without full server (addresses toolhive#2852)
   - Enable future features through interface decoration

4. **Revised Implementation Plan**:
   - Phase 1: Introduce Session/SessionFactory interfaces
   - Phase 2: Wire SessionManager to SDK
   - Phase 3: Migrate existing code to use Session interface
   - Phase 4: Cleanup and observability

5. **Added Benefits Documentation**:
   - Concrete examples of decorator pattern (optimizer-in-vmcp)
   - Simplified capability refresh approach
   - Clear testing strategy without server dependency

6. **Fixed Formatting Issues** (from Copilot review):
   - Split Goals & Non-Goals into separate sections
   - Changed "Security" to "Security Considerations"
   - Restructured Compatibility section
   - Fixed References to use full repo-qualified format
   - Added credential refresh considerations

The RFC now addresses the architectural root cause (scattered session
concerns) rather than just the symptom (per-request client creation).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
yrobla added a commit that referenced this pull request Feb 9, 2026
Refactor RFC to address scattered session architecture concerns

Address architectural feedback from PR #38 review, specifically jerm-dro's
comments about the root cause being scattered session concerns rather than
just client lifecycle management.

Major changes:

1. **Expanded Problem Statement**:
   - Identified root cause: session concerns scattered across middleware,
     adapters, and hooks
   - Current VMCPSession is a passive data container, not a domain object
   - Session construction tangled with SDK lifecycle callbacks
   - Hard to create session-scoped resources (clients, optimizer features)

2. **Introduced Core Interfaces**:
   - Session interface: Domain object that owns clients, encapsulates routing,
     manages lifecycle (not just a data container)
   - SessionFactory interface: Creates fully-formed sessions with all
     dependencies (discovery, client init, routing setup)
   - SessionManager: Bridges between domain (Session) and protocol (SDK)

3. **Updated Goals**:
   - Primary goal: Encapsulate session behavior in clean interfaces
   - Decouple session creation from SDK wiring
   - Enable testing without full server (addresses toolhive#2852)
   - Enable future features through interface decoration

4. **Revised Implementation Plan**:
   - Phase 1: Introduce Session/SessionFactory interfaces
   - Phase 2: Wire SessionManager to SDK
   - Phase 3: Migrate existing code to use Session interface
   - Phase 4: Cleanup and observability

5. **Added Benefits Documentation**:
   - Concrete examples of decorator pattern (optimizer-in-vmcp)
   - Simplified capability refresh approach
   - Clear testing strategy without server dependency

6. **Fixed Formatting Issues** (from Copilot review):
   - Split Goals & Non-Goals into separate sections
   - Changed "Security" to "Security Considerations"
   - Restructured Compatibility section
   - Fixed References to use full repo-qualified format
   - Added credential refresh considerations

The RFC now addresses the architectural root cause (scattered session
concerns) rather than just the symptom (per-request client creation).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@yrobla yrobla force-pushed the session-scoped-mcp-client branch from d698c3e to 9654f19 Compare February 9, 2026 15:16
yrobla added a commit that referenced this pull request Feb 9, 2026
Refactor RFC to address scattered session architecture concerns

Address architectural feedback from PR #38 review, specifically jerm-dro's
comments about the root cause being scattered session concerns rather than
just client lifecycle management.

Major changes:

1. **Expanded Problem Statement**:
   - Identified root cause: session concerns scattered across middleware,
     adapters, and hooks
   - Current VMCPSession is a passive data container, not a domain object
   - Session construction tangled with SDK lifecycle callbacks
   - Hard to create session-scoped resources (clients, optimizer features)

2. **Introduced Core Interfaces**:
   - Session interface: Domain object that owns clients, encapsulates routing,
     manages lifecycle (not just a data container)
   - SessionFactory interface: Creates fully-formed sessions with all
     dependencies (discovery, client init, routing setup)
   - SessionManager: Bridges between domain (Session) and protocol (SDK)

3. **Updated Goals**:
   - Primary goal: Encapsulate session behavior in clean interfaces
   - Decouple session creation from SDK wiring
   - Enable testing without full server (addresses toolhive#2852)
   - Enable future features through interface decoration

4. **Revised Implementation Plan**:
   - Phase 1: Introduce Session/SessionFactory interfaces
   - Phase 2: Wire SessionManager to SDK
   - Phase 3: Migrate existing code to use Session interface
   - Phase 4: Cleanup and observability

5. **Added Benefits Documentation**:
   - Concrete examples of decorator pattern (optimizer-in-vmcp)
   - Simplified capability refresh approach
   - Clear testing strategy without server dependency

6. **Fixed Formatting Issues** (from Copilot review):
   - Split Goals & Non-Goals into separate sections
   - Changed "Security" to "Security Considerations"
   - Restructured Compatibility section
   - Fixed References to use full repo-qualified format
   - Added credential refresh considerations

The RFC now addresses the architectural root cause (scattered session
concerns) rather than just the symptom (per-request client creation).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

Update Last Updated date to 2026-02-09
jerm-dro
jerm-dro previously approved these changes Feb 13, 2026
Copy link

@jerm-dro jerm-dro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes motivated by others' feedback LGTM.

JAORMX
JAORMX previously approved these changes Feb 16, 2026
@yrobla
Copy link
Contributor Author

yrobla commented Feb 16, 2026

Different advices collected:

  • one different session per vmcp per client, how it will affect the current RFC - that's a problem with the transport and single endpoint
  • sessions in one mcp can terminate before others
  • investigate if we could replace this with Stateful Streamable HTTP, and will be the implementation that is needed. Can we assume that all MCP servers support it?
  • we can create a test suite to validate that on multiple clients - but this should also be better done at MCP level, and we could reuse for vMCP

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@yrobla yrobla force-pushed the session-scoped-mcp-client branch from a415e4f to 0682b34 Compare February 16, 2026 16:06
@yrobla yrobla force-pushed the session-scoped-mcp-client branch from 0682b34 to 0ca7b5a Compare February 17, 2026 15:56
@yrobla yrobla requested review from amirejaz and Copilot and removed request for Copilot February 17, 2026 16:13
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 13 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@yrobla yrobla merged commit 127fe09 into main Feb 18, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

Comments