In this article
July 14, 2025
July 14, 2025

Understanding Roots in Model Context Protocol (MCP)

Learn how MCP Roots define resource boundaries in distributed systems, enabling clients to scope server behavior with clear, URI-based context declarations.

In distributed systems like those built with Model Context Protocol (MCP), coordinating between clients and servers requires clarity around what resources matter and where they live. That's where Roots come in.

Roots define the boundaries of a workspace, providing a way for clients to declare which resources and locations a server should care about. In this article, we’ll walk through what roots are, how they work in practice, and how developers can leverage them effectively.

What are roots?

A Root in MCP is a URI that represents a location the client wants the server to pay attention to.

When a client connects to a server, it can provide one or more roots — these act as hints or guidance markers for the server to scope its operations. While most commonly used to represent filesystem paths, roots can be any valid URI, including HTTP or custom protocols.

	
file:///Users/alex/dev/dashboard-app
https://services.internal.company.com/api
	

These URIs tell the server: “This is where my world starts. Focus here.”

Why use roots

Roots solve several coordination problems in context-aware systems:

  1. Guidance: Servers know where to begin scanning, watching, or resolving resources.
  2. Organization: Clients can manage multiple resources or workspaces by declaring multiple roots.
  3. Clarity: Both client and server share a common understanding of context scope.

Roots are especially useful in developer tools, editors, or infrastructure orchestration where multiple sources of truth (e.g., local code, remote APIs, configs) need to be accessed coherently.

How roots work in MCP

Here's the basic lifecycle of roots during a client-server interaction:

Client responsibilities

  1. Declare support: The client announces that it supports roots via the roots capability during connection setup.
  2. Send roots: It provides a list of roots (URIs) for the server to work with.
  3. Notify on change: If root changes are dynamic (e.g. switching projects), the client informs the server of updates.

Server responsibilities

  1. Respect scope: The server should prioritize behavior within the declared roots.
  2. Resolve resources: Use the root URIs to locate, load, and operate on relevant resources.
  3. Avoid overreach: Treat roots as boundaries — don’t assume global visibility.

Keep in mind that roots are informational, not strictly enforced, but honoring them leads to better performance and clearer semantics.

Common use cases

You’ll often use roots in these contexts:

Use Case Root URI Example
Project directory file:///home/user/myproject
API endpoint https://api.example.com/v1
Repo mount point file:///repos/shared-lib
Configuration scope file:///etc/myapp/config.yaml
Environment root env://production (hypothetical custom URI)

This model is extensible to any system where location matters and scope needs to be defined.

Best practices for working with roots

  • Be specific: Only declare roots you actually want the server to act on.
  • Use descriptive names: Especially helpful when multiple roots are in use.
  • Handle dynamically: Support updates to roots as users switch projects or configurations.
  • Fail gracefully: Validate root accessibility and inform the user or client app if resolution fails.

Example: Declaring roots in a client

Here’s what a root declaration might look like in a JSON-based MCP client:

	
{
  "roots": [
    {
      "uri": "file:///Users/alex/dev/dashboard-app",
      "name": "Dashboard Codebase"
    },
    {
      "uri": "https://services.internal.company.com/api",
      "name": "Internal API Service"
    }
  ]
}
	

In this setup:

  • The first root tells the server to operate within a local application directory.
  • The second root introduces an external API as a contextual boundary — useful for linking docs, routes, or live service metadata.

Each root is logically separated, allowing for clean graph construction and evaluation on the server side.

Wrap-up

Roots in MCP are a simple but powerful mechanism for defining workspace boundaries and resource scopes. They help clients and servers coordinate more effectively, especially in multi-resource environments.

By treating Roots as declarative scope markers, you enable:

  • Cleaner resolution logic
  • Scoped computation
  • Modular context graphs

Whether you’re integrating MCP into a dev tool, CLI, or orchestration layer, proper use of roots will help your system scale with clarity and composability.

This site uses cookies to improve your experience. Please accept the use of cookies on this site. You can review our cookie policy here and our privacy policy here. If you choose to refuse, functionality of this site will be limited.