In depth
Roots are the scoping mechanism for filesystem-like MCP servers. When a client connects to a server that needs to access local data, the client advertises its roots — a list of URIs representing allowed locations. The server must stay within these boundaries.
A root is typically a directory path: `file:///Users/me/project1`, `file:///Users/me/project2`. Servers like `server-filesystem` read roots at session start and refuse tool calls for paths outside. This is how Claude Code tells the filesystem MCP 'only touch this workspace, not anything else on my disk'.
Roots aren't limited to filesystems. They can be any URI — `postgres://mydb/public`, `https://api.example.com/v1/`. They semantically mean 'the server can operate within this scope'.
The client advertises roots via the `roots` capability. It can notify on changes (`roots/listChanged`) so the server updates its scope dynamically — e.g. when the user opens a new project in Cursor, a new root is added.