MCP Roots Is Deprecated. Where Should Your Bot's File Boundaries Live Now?
MCP Roots is deprecated in the 2026-07-28 specification and cannot be removed before the first revision released on or after 2027-07-28. The old standalone roots/list request works on legacy connections, while the 2026 protocol carries roots/list inside a Multi Round-Trip Request. Neither form enforces filesystem access. This guide distinguishes those wire paths and shows how to move scoping to tool inputs, resource URIs, or server configuration with real OS-level controls.
AI-assisted editorial: researched and drafted with AI using the primary sources linked below. Examples are illustrative; they are not measured product results. Editorial policy.
Key takeaways
- Roots is deprecated in the 2026-07-28 spec; the first eligible removal revision is on or after 2027-07-28, and actual removal is a maintainer decision.
- The old standalone roots/list request needs a legacy connection. A modern 2026 request can carry roots/list inside an InputRequiredResult, but new implementations should use the documented migration paths.
- Roots are advisory, not filesystem access control. Validate paths in the server and restrict the process with permissions or sandboxing.
MCP Deprecated Roots in July 2026. What Exactly Happened
The Model Context Protocol's 2026-07-28 revision marked Roots as deprecated under a new feature lifecycle policy. The official spec page for Roots now states this plainly: new implementations should stop adopting it, and existing ones should move on.
This wasn't an isolated change. The same revision deprecated Sampling and Logging alongside Roots, all under one proposal. The registry entry lists the deprecation SEP for all three as SEP-2577, deprecated in the 2026-07-28 revision, with migration paths spelled out and an earliest removal window of a revision released on or after 2027-07-28.
Deprecated does not mean immediately removed. Roots remains specified in the 2026-07-28 revision, and the first revision eligible to remove it is one released on or after 2027-07-28; removal is still a Core Maintainer decision. But wire behavior matters: the older standalone server-to-client roots/list request works on a legacy, pre-2026 connection, not on a modern stateless connection without a back-channel. The 2026 protocol can instead carry a roots/list input request inside an InputRequiredResult and complete it through Multi Round-Trip Requests. Treat existing integrations according to the protocol version they use, rather than assuming an old request works unchanged everywhere.
Sources: Roots - Model Context Protocol, Deprecated Features - Model Context Protocol, The 2026-07-28 Specification, Deprecated features - MCP Python SDK.
Roots Never Enforced Anything — So What Are You Actually Losing?
Before deciding what to migrate to, it helps to be honest about what Roots ever gave you. The MCP client-concepts documentation is direct about this: roots serve as a coordination mechanism between clients and servers, not a security boundary. The spec only required servers to 'SHOULD respect root boundaries,' not 'MUST enforce' them, because servers run arbitrary code the client cannot fully control.
In practice that meant a compliant client would advertise a directory as a root, and a well-behaved server would stay inside it — but nothing in the protocol stopped a careless or malicious server from reading outside that boundary. Real enforcement always had to happen at the operating-system level: file permissions, container mounts, or bind mounts that physically restrict what a process can touch.
So the deprecation mostly formalizes something that was already true: if you were treating roots as your access-control layer, you were relying on an honor system. Losing roots as a first-class feature doesn't remove a security control you had — it removes a coordination hint you were probably over-trusting.
Sources: Understanding MCP clients - Model Context Protocol.
Worked Example: Migrating a Filesystem Server Off Roots
Consider a hypothetical filesystem MCP server for a personal research bot. In a legacy, handshake-era integration, the client declared a roots capability, the server sent a standalone roots/list request, and it received a file:// URI for a notes folder. The server used that advisory location as context for later tool calls. A modern 2026 connection has no back-channel for that old standalone request; a roots/list input request would have to travel through the new Multi Round-Trip Request flow.
The specification offers three migration paths for new work: pass directories or files through tool parameters, resource URIs, or server configuration. For a fixed notes folder, the server could receive an allowed directory at startup and validate every tool path against it. If client input is genuinely needed during a call, the Python SDK documents putting a ListRootsRequest inside an InputRequiredResult. That is a different wire flow from calling the old standalone roots/list method on a modern connection.
Concretely, that means three tools that used to assume '/reports is the root' now each take a path argument, and your server validates that argument against a server-configured allowlist before touching disk. This is more code up front — you're writing the validation instead of leaning on a protocol field — but it also means the boundary is enforced by your own server logic and, ideally, OS-level permissions, rather than by a value a client merely suggested.
One failure path worth naming: keeping the old standalone roots/list call while switching a connection to the 2026 stateless protocol can fail because there is no server-to-client back-channel. Keeping the old flow on a legacy connection still leaves the root advisory, so a server-side allowlist and OS-level restrictions are needed either way.
Sources: Roots - Model Context Protocol, The 2026-07-28 Specification, Deprecated features - MCP Python SDK.
What to Do With Your Bot Today
If you're building a new MCP server or bot integration, do not adopt Roots as a new dependency. The deprecation registry lists tool parameters, resource URIs, and server configuration as migration paths. Choose based on who should set the scope: a caller-provided path can be a tool argument, while an administrator-controlled boundary belongs in server configuration and filesystem permissions. Validate each input path against that boundary.
If you maintain an existing server, inventory both its Roots use and the protocol versions its clients negotiate. The old standalone request can still work on legacy connections, but it does not carry over unchanged to a 2026 stateless connection. Roots cannot be removed from the specification before the first revision released on or after 2027-07-28; the date is an eligibility floor, not a guaranteed removal date or a clock that restarts with every release. Plan migration against the published registry and your SDK's support policy.
The one thing not to do is treat this purely as a protocol-compliance chore. Because roots were never an enforced boundary, migrating away from them is a good moment to ask whether your server has real access control at all — an OS-level sandbox, a container mount, or at minimum a hard-coded allowlist checked on every call. If the honest answer is 'no, we just trusted the client's root,' fix that as part of the migration, not after it.
Sources: Deprecated Features - Model Context Protocol, The 2026-07-28 Specification, Deprecated features - MCP Python SDK, Feature Lifecycle and Deprecation Policy.
Primary sources
Sources checked 2026-09-30. Standards and product documentation can change; follow the linked version when implementing.
- Roots - Model Context Protocol — Model Context Protocol
- Deprecated Features - Model Context Protocol — Model Context Protocol
- The 2026-07-28 Specification — Model Context Protocol
- Understanding MCP clients - Model Context Protocol — Model Context Protocol
- Deprecated features - MCP Python SDK — Model Context Protocol
- Feature Lifecycle and Deprecation Policy — Model Context Protocol
BotBento is in development. Suggest a correction.