Skip to content

Commit e9216b8

Browse files
authored
Merge pull request modelcontextprotocol#29 from modelcontextprotocol/davidsp/list-roots
Add roots listing capability
2 parents a20f174 + 5f60c57 commit e9216b8

File tree

3 files changed

+402
-5
lines changed

3 files changed

+402
-5
lines changed

docs/spec/roots.md

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
---
2+
title: Roots
3+
type: docs
4+
weight: 8
5+
description: "MCP protocol specification for root directory and file access"
6+
draft: false
7+
params:
8+
author: Anthropic
9+
keywords: ["mcp", "roots", "directories", "files", "protocols"]
10+
---
11+
12+
Roots enable clients to provide a list of root directories or files that servers can operate on. This allows servers to understand which parts of the filesystem they have access to and should work with. Servers can request the list of roots from clients that support this capability, and clients can notify servers when the list of available roots changes.
13+
14+
## Capabilities
15+
16+
To indicate support for roots, clients MUST include a `roots` capability in their `ClientCapabilities` during initialization:
17+
18+
{{<tabs items="Basic,With Notifications">}}
19+
{{<tab>}}
20+
```json
21+
{
22+
"capabilities": {
23+
"roots": { }
24+
}
25+
}
26+
```
27+
{{</tab>}}
28+
{{<tab>}}
29+
```json
30+
{
31+
"capabilities": {
32+
"roots": {
33+
"listChanged": true
34+
}
35+
}
36+
}
37+
```
38+
{{</tab>}}
39+
{{</tabs>}}
40+
41+
The optional `listChanged` property indicates whether the client will send notifications when the root list changes.
42+
43+
Servers SHOULD check for this capability before attempting to use any roots functionality.
44+
45+
## Concepts
46+
47+
### Root
48+
49+
A Root in the Model Context Protocol (MCP) represents a directory or file that a server is allowed to operate on. Each Root is uniquely identified by a URI (currently restricted to file:// URIs) and may have an optional human-readable name. Roots define the boundaries of where servers can work within the filesystem.
50+
51+
{{< callout type="info" >}}
52+
Only URI's starting with **file://** are accepted.
53+
{{< /callout >}}
54+
55+
## Use Cases
56+
57+
Common use cases for roots include defining workspace directories, project repositories, or specific files that a server should analyze or modify. Here are some examples:
58+
59+
### Project Directory
60+
61+
A root representing a project workspace:
62+
63+
```json
64+
{
65+
"uri": "file:///home/user/projects/myproject",
66+
"name": "My Project"
67+
}
68+
```
69+
70+
### Multiple Repositories
71+
72+
Multiple roots for different Git repositories:
73+
74+
```json
75+
[
76+
{
77+
"uri": "file:///home/user/repos/frontend",
78+
"name": "Frontend Repository"
79+
},
80+
{
81+
"uri": "file:///home/user/repos/backend",
82+
"name": "Backend Repository"
83+
}
84+
]
85+
```
86+
87+
## Diagram
88+
89+
The following diagram visualizes the interaction between client and server for roots:
90+
91+
```mermaid
92+
sequenceDiagram
93+
participant Server
94+
participant Client
95+
96+
Note over Server,Client: Server requests roots list
97+
Server->>Client: roots/list
98+
Client-->>Server: ListRootsResult
99+
100+
Note over Server,Client: Client updates roots
101+
opt Roots Changed
102+
Client-)Server: notifications/roots/list_changed
103+
Server->>Client: roots/list
104+
Client-->>Server: ListRootsResult
105+
end
106+
```
107+
108+
## Messages
109+
110+
This section defines the protocol messages for root management in the Model Context Protocol (MCP).
111+
112+
### Listing Roots
113+
114+
#### Request
115+
116+
To retrieve a list of available roots from the client, the server MUST send a `roots/list` request.
117+
118+
Method: `roots/list`
119+
Params: None
120+
121+
Example:
122+
```json
123+
{
124+
"jsonrpc": "2.0",
125+
"id": 1,
126+
"method": "roots/list"
127+
}
128+
```
129+
130+
#### Response
131+
132+
The client MUST respond with a `ListRootsResult` containing:
133+
134+
- `roots`: An array of `Root` objects
135+
136+
A `Root` object consists of:
137+
- `uri`: A URI string identifying the root location. Currently only `file://` URIs are supported. This field is required.
138+
- `name`: An optional string providing a human-readable name for the root.
139+
140+
Example:
141+
```json
142+
{
143+
"jsonrpc": "2.0",
144+
"id": 1,
145+
"result": {
146+
"roots": [
147+
{
148+
"uri": "file:///home/user/projects/myproject",
149+
"name": "My Project"
150+
},
151+
{
152+
"uri": "file:///home/user/repos/backend",
153+
"name": "Backend Repository"
154+
}
155+
]
156+
}
157+
}
158+
```
159+
160+
### Root List Changed Notification
161+
162+
If the client supports the `listChanged` capability for roots, it MUST send a `notifications/roots/list_changed` notification when the list of available roots changes.
163+
164+
#### Notification
165+
166+
Method: `notifications/roots/list_changed`
167+
Params: None
168+
169+
Example:
170+
```json
171+
{
172+
"jsonrpc": "2.0",
173+
"method": "notifications/roots/list_changed"
174+
}
175+
```
176+
177+
Upon receiving this notification, servers SHOULD request an updated root list using the `roots/list` method to ensure they have the most up-to-date information.
178+
179+
## Error Handling
180+
181+
Servers MUST be prepared to handle cases where:
182+
- The client does not support roots
183+
- Listed roots become unavailable
184+
- Access to roots is denied
185+
186+
The client SHOULD return appropriate error responses in these cases.
187+
188+
Example error response:
189+
```json
190+
{
191+
"jsonrpc": "2.0",
192+
"id": 1,
193+
"error": {
194+
"code": -32601,
195+
"message": "Roots not supported",
196+
"data": {
197+
"reason": "Client does not have roots capability"
198+
}
199+
}
200+
}
201+
```
202+
203+
## Security Considerations
204+
205+
Implementations MUST carefully consider:
206+
207+
- Access control for root directories and files
208+
- Validation of root URIs to prevent path traversal attacks
209+
- Scope limitations to prevent unauthorized access
210+
- Permission checks before exposing roots
211+
- Regular validation that roots remain accessible
212+
213+
Clients SHOULD:
214+
- Only expose roots that the server has permission to access
215+
- Validate all root URIs before returning them
216+
- Implement proper filesystem permission checks
217+
- Monitor for changes in root accessibility

schema/schema.json

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,16 @@
8080
"description": "Experimental, non-standard capabilities that the client supports.",
8181
"type": "object"
8282
},
83+
"roots": {
84+
"description": "Present if the client supports listing roots.",
85+
"properties": {
86+
"listChanged": {
87+
"description": "Whether the client supports notifications for changes to the roots list.",
88+
"type": "boolean"
89+
}
90+
},
91+
"type": "object"
92+
},
8393
"sampling": {
8494
"additionalProperties": true,
8595
"description": "Present if the client supports sampling from an LLM.",
@@ -96,6 +106,9 @@
96106
},
97107
{
98108
"$ref": "#/definitions/ProgressNotification"
109+
},
110+
{
111+
"$ref": "#/definitions/RootsListChangedNotification"
99112
}
100113
]
101114
},
@@ -136,6 +149,9 @@
136149
},
137150
{
138151
"$ref": "#/definitions/CompleteRequest"
152+
},
153+
{
154+
"$ref": "#/definitions/ListRootsRequest"
139155
}
140156
]
141157
},
@@ -146,6 +162,9 @@
146162
},
147163
{
148164
"$ref": "#/definitions/CreateMessageResult"
165+
},
166+
{
167+
"$ref": "#/definitions/ListRootsResult"
149168
}
150169
]
151170
},
@@ -810,6 +829,54 @@
810829
],
811830
"type": "object"
812831
},
832+
"ListRootsRequest": {
833+
"description": "Sent from the server to request a list of root URIs from the client. Roots allow\nservers to ask for specific directories or files to operate on. A common example\nfor roots is providing a set of repositories or directories a server should operate\non.\n\nThis request is typically used when the server needs to understand the file system\nstructure or access specific locations that the client has permission to read from.",
834+
"properties": {
835+
"method": {
836+
"const": "roots/list",
837+
"type": "string"
838+
},
839+
"params": {
840+
"additionalProperties": {},
841+
"properties": {
842+
"_meta": {
843+
"properties": {
844+
"progressToken": {
845+
"$ref": "#/definitions/ProgressToken",
846+
"description": "If specified, the caller is requesting out-of-band progress notifications for this request (as represented by notifications/progress). The value of this parameter is an opaque token that will be attached to any subsequent notifications. The receiver is not obligated to provide these notifications."
847+
}
848+
},
849+
"type": "object"
850+
}
851+
},
852+
"type": "object"
853+
}
854+
},
855+
"required": [
856+
"method"
857+
],
858+
"type": "object"
859+
},
860+
"ListRootsResult": {
861+
"description": "The client's response to a roots/list request from the server.\nThis result contains an array of Root objects, each representing a root directory\nor file that the server can operate on.",
862+
"properties": {
863+
"_meta": {
864+
"additionalProperties": {},
865+
"description": "This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses.",
866+
"type": "object"
867+
},
868+
"roots": {
869+
"items": {
870+
"$ref": "#/definitions/Root"
871+
},
872+
"type": "array"
873+
}
874+
},
875+
"required": [
876+
"roots"
877+
],
878+
"type": "object"
879+
},
813880
"ListToolsRequest": {
814881
"description": "Sent from the client to request a list of tools the server has.",
815882
"properties": {
@@ -1353,6 +1420,48 @@
13531420
},
13541421
"type": "object"
13551422
},
1423+
"Root": {
1424+
"description": "Represents a root directory or file that the server can operate on.",
1425+
"properties": {
1426+
"name": {
1427+
"description": "An optional name for the root. This can be used to provide a human-readable\nidentifier for the root, which may be useful for display purposes or for\nreferencing the root in other parts of the application.",
1428+
"type": "string"
1429+
},
1430+
"uri": {
1431+
"description": "The URI identifying the root. This *must* start with file:// for now.\nThis restriction may be relaxed in future versions of the protocol to allow\nother URI schemes.",
1432+
"format": "uri-template",
1433+
"type": "string"
1434+
}
1435+
},
1436+
"required": [
1437+
"uri"
1438+
],
1439+
"type": "object"
1440+
},
1441+
"RootsListChangedNotification": {
1442+
"description": "A notification from the client to the server, informing it that the list of roots has changed.\nThis notification should be sent whenever the client adds, removes, or modifies any root.\nThe server should then request an updated list of roots using the ListRootsRequest.",
1443+
"properties": {
1444+
"method": {
1445+
"const": "notifications/roots/list_changed",
1446+
"type": "string"
1447+
},
1448+
"params": {
1449+
"additionalProperties": {},
1450+
"properties": {
1451+
"_meta": {
1452+
"additionalProperties": {},
1453+
"description": "This parameter name is reserved by MCP to allow clients and servers to attach additional metadata to their notifications.",
1454+
"type": "object"
1455+
}
1456+
},
1457+
"type": "object"
1458+
}
1459+
},
1460+
"required": [
1461+
"method"
1462+
],
1463+
"type": "object"
1464+
},
13561465
"SamplingMessage": {
13571466
"description": "Describes a message issued to or received from an LLM API.",
13581467
"properties": {
@@ -1464,6 +1573,9 @@
14641573
},
14651574
{
14661575
"$ref": "#/definitions/CreateMessageRequest"
1576+
},
1577+
{
1578+
"$ref": "#/definitions/ListRootsRequest"
14671579
}
14681580
]
14691581
},

0 commit comments

Comments
 (0)