Skip to content

Soft-roots-first workspace roots: native MCP roots as seed, mutable session-scoped soft roots as source of truth #73

Description

@carldebilly

Context

MCP native Roots is deprecated (SEP-2577, no successor for this use case) and nearly static in practice: hosts rarely expose UI to change roots mid-session, and roots/list_changed is host-initiated only. Soft roots (SetSoftRoots) are portable across every Repl channel (CLI, REPL, hosted sessions, MCP), testable, and mutable mid-session — but today they are shadowed by hard roots whenever the client supports the Roots capability, and they are handler-global mutable state.

Proposed design

  1. Soft roots become the canonical source of truth for IMcpClientRoots.Current (and likely a channel-neutral abstraction promoted out of Repl.Mcp, e.g. IReplWorkspaceRoots).
  2. Native MCP roots act as a seed: when the client provides roots, they initialize the session's soft roots at session start (and on roots/list_changed), then the soft set lives its own life. This inverts today's precedence, where hard roots shadow soft roots and a model cannot refocus its scope on a roots-capable host.
  3. Mutation is opt-in and app-controlled: no mutating tool is exposed by default. Roots-as-security-boundary must remain possible — letting the model rewrite its own scope is self-escalation (workspace use C:\), so apps that want dynamism map an explicit command (and can mark it .Destructive()).
  4. Session-scoped state: soft roots become per-session, not handler-global. Depends on Scoped DI services are shared across hosted sessions despite per-session documentation #70 (per-session DI scopes) for the natural home of that state.
  5. Deprecation insulation: when the SDK removes the Roots surface, only the seed layer disappears.

Priority

Modest — multi-session MCP with roots (stdio) is rare today; the value grows with HTTP hosting (PR #27) and WebSocket/Telnet hosts.

Dependencies

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions