What are Roots in MCP
What are Roots in MCP
As Large Language Models (LLMs) become more popular, MCP is also experiencing significant growth. According to research by Pulse, MCP server downloads reached approximately 8 million as of April 2025 - a 33% increase from March. Each month, many new MCP servers are also being introduced. If you're into AI and curious about MCP, it makes sense to understand its key concepts, among which are roots. In this article, we’ll dive deep into MCP roots and how they are useful.
What is MCP?
Before we discuss Roots, let’s take a quick look at what MCP actually is.
MCP stands for Model Context Protocol. It standardizes the way AI models communicate or connect with external tools, data sources, and functions. It basically enables AI applications or assistants to manage and structure context for LLMs, allowing them to perform actions beyond generating text. These actions could include searching the web, sending an email or message, accessing a database, or even making a payment.
For example, ChatGPT’s Code Interpreter or Advanced Data Analysis feature uses MCP to perform actions beyond mere text generation. It can directly run Python code, analyze files, and generate visualizations directly within the chat interface.
With MCP, we can also build complex LLM-based workflows or multi-agent systems where multiple LLMs are working as specialists. MCP allows multiple LLMs to interact and collaborate by defining how context is represented and shared between them.
Understanding Roots in MCP
MCP roots, or roots for short, define the boundaries within which MCP servers can operate. They are essentially Uniform Resource Identifiers (URIs) that the MCP clients specify for the servers, telling them where they should focus or the specific areas they are allowed to work within. For example, roots can represent local directories, remote APIs, or other resources that the server needs to access.
When an AI agent interacts with your system, roots define what directories and files the agent can access. Basically, the agent provides a root to the server. The server then accesses the files in that root,generates a structured resource template, and provides it to the LLM. The model can refer to the template and make individual requests for specific resources it needs to interact with.
Roots are commonly filesystem paths, but they can be any valid URI. This also includes HTTP URLs.
Here is an example root for a project directory:
file:///desktop/user/projects/aiapp
Example root for database connections:
db://myorg/clients
It’s important to note here that while the client specifies which roots the server is allowed to work within, the server isn’t bound to follow these boundaries. Ideally, the server should limit itself to these boundaries but the MCP Specification itself doesn’t dictate that the server must follow these limits — it provides a standardized way to share root information.
How are MCP Roots Useful?
MCP roots are useful as they allow clients to define clear boundaries for where a server can operate. This allows for better control in terms of how the server behaves. Key benefits of roots include:
1. Relevance and Focus
Roots tell servers where they should focus and which information to access. This way, the server focuses only on the relevant information. This improves the quality of responses, reduces unnecessary output, and helps the model perform actions based on user goals.
2. Enhanced Performance
By limiting the scope of access for servers, roots improve server performance. The server only searches within specific resources, requiring less processing, searching, and filtering. This increases response speed and enhances the overall performance of the AI assistant or LLM.
3. Standardized Communication
MCP roots provides a standardized way for the client to communicate context boundaries to the server. This makes it easier to build interoperable systems where different clients and servers can work together using the same protocol.
In other words, any client and server that follow the MCP specification can work together without needing custom integration logic.
4. Security
By defining the boundaries within which the server can operate, roots keep the server from accessing the resources not meant for it. For example, in a healthcare system, roots can limit the server or assistant’s access to only cardiology records. This helps avoid accidental access to other confidential data.
However, the security benefit is only there if the server is properly configured to respect root boundaries. It’s not bound by the MCP specification to follow these boundaries.
How Do Roots work in MCP?
Here’s a step-by-step explanation of how roots in MCP work:
- When the client and server first connect, the client informs the server that it supports roots.
- The server requests available roots.
- The client provides a list of available roots and instructs the server that it can only access these specific resources.
- If a user wants to change the list of roots the server can access, it will inform the client.
- The client informs the server that the list of roots has been updated and that the server should access only these roots.
Take, for example, a hospital that has an MCP server. The hospital can ask its client to limit the server to only specific medical departments.
The client will ask the user (such as the hospital administrator) to select the departments it wants the server to access. The client will then notify the server that the list of roots has been updated. The server will request the new roots and will limit its access and actions to the selected departments.
Implementing MCP Roots
Here we’ll provide a simple coding example for implementing MCP Roots in Python using FastMCP (server implementation):
import asyncio
from mcp.server.stdio import stdio_server
from mcp.server import InitializationOptions, NotificationOptions
# Create the MCP server instance
assistant = FastMCP("Department Scope Server")
# Provide available context roots to the client (e.g., hospital departments)
@assistant.resource("roots://departments")
def available_departments():
return {
"roots": [
{
"uri": "file:///data/medical/cardiology",
"name": "Cardiology Records"
},
{
"uri": "https://api.hospital.org/neurology",
"name": "Neurology API"
}
]
}
# Define a sample tool that interacts with one of the selected roots
@assistant.tool()
def analyze_record(file_path: str) -> str:
return f"Analyzing medical record: {file_path}"
# Launch the MCP server over stdio
async def launch():
async with stdio_server() as (reader, writer):
await assistant.run(
reader,
writer,
InitializationOptions(
server_name="dept-scope-server",
server_version="0.2.1",
capabilities=assistant.get_capabilities(
notification_options=NotificationOptions(),
experimental_capabilities={},
),
)
)
if __name__ == "__main__":
asyncio.run(launch())
The above code defines an MCP server using the FastMCP Python framework. The server provides a list of available roots (in our example, different healthcare departments).
Final Thoughts
MCP enables AI assistants to manage and structure context for LLMs. It defines how the assistant should structure the request, represent contextual information, and interpret the results, enabling LLMs to actually do things instead of just saying them.
In MCP, roots are a key concept that allow a client to define operational boundaries within which a server can function and operate. While the server should ideally stay within these boundaries, the MCP specification doesn’t dictate how the server must handle roots. This means the server can implement root handling the way it wants if it’s not configured properly to respect root boundaries.
MCP roots are helpful in various ways. They tell the server which specific information to focus on, improving the quality of responses. This also helps improve the server's speed, as it requires less processing, searching, and filtering. Additionally, if the server is properly configured to follow root boundaries, root prevents it from accessing confidential information not meant for it.