In MCP, what are roots, and what may a Root's uri point to?
answer
- client tells server where to work
- only one URI scheme allowed
- a label, not a lock
- deprecated in the current revision
- file:// uri plus optional name
basics
~20 sRoots are file:// URIs a client gives a server to say which directories or files it is meant to work within. Each Root carries that uri plus an optional human-readable name. MCP revision 2026-07-28 deprecates the whole feature.
solid answer
~40 sA **root** is one entry in a list a client can hand an MCP server describing the filesystem locations the server is expected to operate on — typically the project folders the user has open. The shape is small: `uri`, which MUST be a `file://` URI naming a directory or a file, and an optional `name` used only as a display label in a UI or a log line. A client declares support by including `roots` in its per-request `io.modelcontextprotocol/clientCapabilities`; in revision 2026-07-28 that capability is an empty object `{}`. Roots are informational — they tell a server where to look, they do not restrict what it can reach. Note that 2026-07-28 deprecates roots (SEP-2577); new servers are directed to take paths as ordinary tool parameters instead.
code
json · 6 lines{
"roots": [
{ "uri": "file:///home/alice/projects/api", "name": "API service" },
{ "uri": "file:///home/alice/projects/web" }
]
}go deeper
Be able to say a root is a file:// directory or file the client tells the server about, with an optional display name, and that it is a hint rather than a restriction.
Explain the schema precisely — file:// only, optional name — and where the list comes from: the client declares a roots capability, the server asks for it, the client answers. Mention that 2026-07-28 deprecates it.
Show you know roots never gave isolation and that real confinement is an OS or container concern. Be ready to say what you would use instead in a server you ship today.
Frame roots as a feature that encoded client-side context into the protocol and was withdrawn once explicit tool parameters proved simpler. Own the call on whether your fleet keeps answering roots requests through the deprecation window.
## What a root is When a user opens an IDE or a desktop LLM application on a project, the application knows something the MCP server does not: which folders on this machine the user is actually working in. Roots are the mechanism MCP defined for passing that knowledge across. A client publishes a list of roots, and a server that would otherwise have no idea where to start — a code-search server, a linter, a build-runner — can begin at the right place instead of guessing or scanning the whole disk. ## The schema A `Root` object has two fields that matter: - `uri` — required. It MUST be a `file://` URI. It may name a directory (`file:///home/alice/projects/api`) or an individual file. Other schemes are not permitted here, which is why roots never became a general "here is a data source" mechanism: an `https://` endpoint or a `git://` repository cannot be expressed as a root at all. Those belong to MCP resources, which do accept many URI schemes. - `name` — optional, human-readable. It exists for display: a client UI listing what a server was told, or a log line that reads better than a raw path. Servers must not attach meaning to it. The list of roots is returned inside a `ListRootsResult`, whose `roots` field is an array of these objects. A client that supports roots advertises the `roots` capability inside `io.modelcontextprotocol/clientCapabilities` in the `_meta` of every request it sends; as of revision 2026-07-28 that capability object is empty (`{}`), because the `listChanged` sub-capability it used to carry was removed along with the change notification itself. ## What roots are for, and what they are not for Roots are a **hint about scope**, expressed by the client, for the server's benefit. A file-search server told that the roots are two project directories can index those two trees and skip the rest of the home directory. A test-runner server can resolve a relative path against the first root rather than against its own working directory. What roots are *not* is a sandbox. Nothing in the protocol prevents the server process from opening any file the operating system lets it open. A server that ignores the roots it was given is not violating a security control; it is at most ignoring a suggestion. Isolation, if you want it, has to come from outside MCP — a container, a restricted user account, a filesystem namespace. ## How a server gets them Before revision 2026-07-28 a server could send a `roots/list` request to the client whenever it liked, because servers could originate JSON-RPC requests. That direction of traffic no longer exists. In 2026-07-28 a server that needs roots answers the client's `tools/call`, `prompts/get` or `resources/read` with an interim result whose `resultType` is `"input_required"`, placing a `roots/list` request in its `inputRequests` map; the client resolves it and re-issues the original request carrying the answer. The client can simply not re-issue, which is how declining is expressed — there is no refusal message. ## Deprecated as of 2026-07-28 Revision 2026-07-28 marks roots deprecated (SEP-2577). Deprecated does not mean gone: the feature stays in the specification for at least twelve months, so the earliest revision that may drop it is the first one released on or after 2027-07-28. Until then servers may still request roots, and clients may still answer. New implementations SHOULD NOT adopt it. The migration the specification names is to pass directories and files explicitly — as tool parameters, as resource URIs, or through server configuration — which is more honest about what was happening anyway: the path was always just data the server chose to use. ## What to say in an interview Describe roots as an advisory, client-supplied list of `file://` locations with an optional display name; say plainly that they are not access control; and place them correctly in time — a legitimate part of the protocol, deprecated in 2026-07-28, with tool parameters as the replacement.
- Why can a root not be an https:// or git:// URI?The specification constrains `Root.uri` to the `file://` scheme, so roots only ever expressed local filesystem locations. Anything reachable over a network is modelled as an MCP resource instead: `resources/list` and `resources/read` accept `https://`, `git://` and other RFC 3986 schemes. Trying to squeeze a remote source into a root was never legal, which is one reason roots stayed a narrow, IDE-shaped feature.
- If a client supports roots but has no folders open, what should it return?An empty `roots` array. That is a meaningful answer — it says the client has nothing to scope the server to — and it is different from not supporting the capability at all. A server receiving an empty list should fall back to whatever it does without guidance, such as requiring an explicit path argument, rather than inferring that it may roam the filesystem.
- Should a new MCP server written today declare that it uses roots?No. Revision 2026-07-28 deprecates roots and states that new implementations SHOULD NOT adopt deprecated features. Take the directory or file as a normal tool parameter with a documented `inputSchema`, or read it from server configuration. That works against every client, is visible to the user at the call site, and will not need rewriting when roots are eventually removed after 2027-07-28.
Roots are like telling a contractor which rooms of the house the job covers. It shapes where they start work; it is not a lock on the other doors.
saying these in an interview costs you the question
- Says roots sandbox the server to those directories
- Claims a root can be an https:// or git:// URI
- Describes roots as current best practice in 2026-07-28
- Confuses roots with MCP resources exposed by the server
- Thinks the server chooses its own roots