TellWorldAI World Archive
Ask中文

Home›Practice›Practice

Practice

MCP Roots: Telling Servers Which Files Are Relevant

MCP roots let a client tell a server which file locations are relevant. They are hints, not access control, and they are deprecated in MCP 2026-07-28. New projects should use tool parameters, resource URIs, or server configuration.

Who this is for

This is for developers building MCP servers, or file-handling tools, who run into roots in older examples. After reading, you should be able to say what roots are and are not, and choose a replacement for a new project.

What roots are

Roots are a way for an MCP client to tell a server which filesystem locations matter for the current request. Each root has a file:// URI and an optional display name [1]. A client returns them in this shape:

{
  "roots": [
    {
      "uri": "file:///home/user/projects/weather-service",
      "name": "Weather Service"
    }
  ]
}

Roots are not access control

This is the point most often misunderstood. Roots are hints. They are not a store of conversation history, not a protocol session, and not a permission system. The protocol does not force a server to stay inside the listed roots [1]. Clients should expose only locations the user has approved. Servers should treat roots as a guide to which files are probably relevant, not as proof that they may read them [1].

Deprecated in MCP 2026-07-28

Roots are deprecated in MCP revision 2026-07-28. They stay in that revision for compatibility, and they are eligible for removal in the first specification revision released on or after July 28, 2027 [1]. New implementations should not build on them.

How the 2026-07-28 flow works

A client that supports roots declares the capability in every request, under _meta [1]:

{
  "_meta": {
    "io.modelcontextprotocol/clientCapabilities": {
      "roots": {}
    }
  }
}

When a server needs the roots while handling a request, it can return an InputRequiredResult that asks for roots/list [1]:

{
  "resultType": "input_required",
  "inputRequests": {
    "workspaceRoots": {
      "method": "roots/list"
    }
  },
  "requestState": "opaque-state-from-server"
}

The client then collects the approved roots and sends the request again, sending back the matching inputResponses and the requestState unchanged [1]. The round trip is what keeps the protocol stateless. There is no initialize handshake and no session at the protocol level [1].

What changed from 2025-11-25

Under MCP 2025-11-25, clients advertised roots during initialization. A server could send a direct roots/list request, and a client could send notifications/roots/list_changed when its roots changed [1]. This is legacy behavior. Do not mix those initialization and notification examples into a 2026-07-28 implementation [1].

What to use instead

There are three replacements [1].

  1. Tool parameters. Put the directory or file you need into the tool's input schema as an explicit, required argument:
{
  "name": "analyze_project",
  "inputSchema": {
    "type": "object",
    "properties": {
      "projectDirectory": {
        "type": "string",
        "description": "Approved project directory to analyze"
      }
    },
    "required": ["projectDirectory"]
  }
}
  1. Resource URIs. If the server can expose the relevant files under stable URIs, use MCP Resources. Discovery and retrieval are then both explicit.
  1. Server configuration. For a fixed deployment, set the allowed directories when the server starts. This is often clearer than discovering them during a tool call.

Security checks to keep

Whichever replacement you pick, these requirements apply to every option [1]:

  • Get user consent before exposing filesystem locations.
  • Canonicalize and validate paths to block traversal.
  • Enforce authorization and sandboxing on their own, without relying on root values.
  • Recheck permissions when a file is accessed, not only when it is listed.
  • Do not put sensitive paths in logs or error messages.

How to tell which version an old example targets

Under 2025-11-25, clients declare roots during initialization, a server can send roots/list directly, and clients can send notifications/roots/list_changed when roots change [1]. Under 2026-07-28, the capability is declared in _meta on every request, and the server asks for roots with an InputRequiredResult [1]. Code that mixes an initialization handshake with InputRequiredResult combines two versions, which is not recommended [1].

Why roots are not a permission system

Clients should expose only the locations the user has approved [1]. Servers should treat roots as a guide to relevant files, and still canonicalize and validate paths to block traversal [1]. Permission checks belong at access time, because a file allowed when it was listed may not be allowed when it is opened [1]. Keep sensitive paths out of logs and error messages [1].

Choosing among the replacements

Tool parameters are the most direct option: the directory or file arrives as a required argument and is visible in the schema [1]. Resource URIs suit servers that can expose files under stable URIs, which keeps discovery and retrieval explicit [1]. Server configuration suits fixed deployments, where the allowed directories are set at startup rather than discovered during a tool call [1].

Common questions

Can I rely on roots to limit what a server can read? No. Roots are not an access-control mechanism, and the protocol does not enforce them [1]. Put the limit in the server's own code, configuration, and permission checks.

Why check permissions again at read time? A file that was listed earlier may no longer be allowed when it is actually opened. Checks have to happen at access time, not only at listing time [1].

Adapted from the MCP Roots section of Microsoft's open-source course *MCP for Beginners*[1], released under the MIT License.

Sources

  1. 1
    MCP Roots (Legacy Feature)Microsoft mcp-for-beginners (MIT)

Cite this page: MCP Roots: Telling Servers Which Files Are Relevant. TellWorld, https://www.tellworld.net/practice/practice-mcp-root-contexts. Updated 2026-11-14

Related news

View all