Skip to content

Follow-ups from PR #71 review panel (MCP SDK 2.2.0) #95

Description

@carldebilly

Findings from the eight-lens panel on PR #71 that were deliberately not fixed there, each with the
reason. The two largest were split out at the time: #94 (frozen catalog / */list_changed, still open)
and #93 (MCP App resource handlers miss the flowing request, since closed).

Three of the original findings have since moved out of this issue. What remains below is internal
shape with no consumer path.

What remains: readability and hardening, no consumer path

  • McpServerHandler gained a session registry (_sessions, _attachLock, attach/detach,
    routing-subscription lifetime, per-session intro fan-out) on top of options building, seven request
    handlers, primitive generation and the compatibility shim. Two reasons to change in one class, and
    session lifetime is the concern most likely to move when Scoped DI services are shared across hosted sessions despite per-session documentation #70 lands its per-session overlay. An
    internal McpSessionRegistry holding the contexts is the shape.
  • McpSessionContext.SnapshotGate exposes a raw SemaphoreSlim whose acquire/release protocol
    lives in the handler, while every other member of the type encapsulates its own invariant.
    ValueTask<IDisposable> AcquireSnapshotGateAsync(ct) keeps the primitive private.
  • McpSessionContext is registered into its own service overlay by its caller, so an instance can
    exist whose Services cannot resolve it — a state ResolveContext treats as fatal, guarded only by
    a comment. A static McpSessionContext.Create(...) that builds the overlay, constructs and
    self-registers in one step removes the caller obligation.
  • McpRequestServerAccessor.Current and .Effective name two views of one slot with unrelated
    adjectives; call sites read servers.Effective beside servers.Current. CurrentRequest /
    CurrentServer says what each returns.

What stays with #70

Soft roots remain process-wide on the reused-options path: host-set state with no request to belong to,
which is the DI-scoping question #70 exists for. So do the shared snapshot cache and compatibility-intro
flag on that path — currently harmless, since the catalog is pre-built and the shim only exists behind
handlers.

A CreateMcpServer(ITransport, …) entry point — context + McpServer.Create + attach/detach, for hosts
that control connection creation — would give custom transports session-grade isolation including soft
roots, and is a strong candidate for closing #70 for that shape. It is a feature, not a fix.

Origin: PR #71 review panel (issue #51), wave 5.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions