Skip to content

RFC: Session-Scoped Architecture for vMCP#38

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

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

Conversation

@yrobla
Copy link
Copy Markdown
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
Copy Markdown
Contributor

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.

Comment thread rfcs/THV-0034-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0034-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0034-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0034-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0034-session-scoped-client-lifecycle.md Outdated
@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
Copy Markdown
Contributor

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.

Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0034-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0034-session-scoped-client-lifecycle.md Outdated
@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
Copy Markdown
Contributor

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.

Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
@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
Copy Markdown
Contributor

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.

Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
@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
Copy Markdown
Contributor

@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.

Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
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
Copy link
Copy Markdown
Contributor

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.

Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Copy link
Copy Markdown
Contributor

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 no new 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 6d03d71 to 6bcdb92 Compare February 12, 2026 10:53
@jerm-dro
Copy link
Copy Markdown
Contributor

@JAORMX Thanks for the review and context around transportsession.Manager!

I'm not opposed to preserving the existing session storage mechanism as part of this work. The main thrust of this RFC is encapsulating the session concept and behavior into a coherent domain object, and, based on my read of the code, that can still be accomplished without changing the storage mechanism.

That said, it's worth acknowledging that we're currently paying a cognitive cost to maintain the storage abstraction layer ahead of a distributed backend that doesn't exist yet. I'd be curious to hear your thoughts on the timeline for that work, since it would help us calibrate how much we invest in preserving compatibility with it right now vs. keeping things simple.

In the future, I also think it's worth exploring whether we can simplify the transportsession.Manager API. For example, rather than the current get/set pattern on the Manager, an alternative factoring could have the Session object become the sole owner of its state and expose a Marshal() method that produces a serialized representation on demand. That would make the ownership of data clearer and the storage layer thinner. But that's beyond the scope of this RFC and something we can think through at a later date. When we design this in earnest, we should think deeper about what state can change, when it changes how we signal to update its stored representation, etc.

Copy link
Copy Markdown
Contributor

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 11 comments.


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

Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
JAORMX
JAORMX previously approved these changes Feb 13, 2026
Copy link
Copy Markdown
Contributor

@JAORMX JAORMX left a comment

Choose a reason for hiding this comment

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

Thanks for addressing the feedback, Yolanda! The integration with transportsession.Manager (instead of a parallel sync.Map), the dual-layer storage model (metadata vs. runtime), and the composition model (defaultSession embedding transportsession.Session) all look good. This preserves the Redis/Valkey externalization path we built out in #1677/#1989/#1770/#1771 while delivering the session encapsulation improvements.

LGTM!

jerm-dro
jerm-dro previously approved these changes Feb 13, 2026
Copy link
Copy Markdown
Contributor

@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
Copy Markdown
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
Copy Markdown
Contributor

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.

Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Copy link
Copy Markdown
Contributor

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.

Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md Outdated
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
Copy link
Copy Markdown
Contributor

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.

Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
Comment thread rfcs/THV-0038-session-scoped-client-lifecycle.md
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.

6 participants