DS DevShelfHub Projects · AI tools
Tutorials / MCP / Reference / Interfaces / Root
Interface client-features modelcontextprotocol/types

Root

By DevShelfHub

A filesystem or URI scope the client exposes to servers.

What is Root?

A `Root` is the unit of scope that a client communicates to servers during a session. Each root holds exactly two fields: a mandatory `uri` (typically a `file://` path, but any URI scheme is legal) and an optional human-readable `name`. Together, a list of roots forms the bounding box for everything the server is expected to care about — the open project folders, a mounted network share, or a custom `workspace://` scheme are all valid shapes. The interface lives in `modelcontextprotocol/types` and is returned as `Root[]` through the `roots/list` request.

In the MCP message flow, roots enter the picture after `initialize` completes. The server calls `roots/list` (a server-to-client request, unusually) to retrieve the current list, caches it, and uses those prefixes when deciding which paths to surface as resources and which tool arguments to accept. If the client declared `roots.listChanged: true` in its capabilities, it will emit `notifications/roots/list_changed` whenever the workspace changes — for example when the user opens or closes a folder — and the server should re-call `roots/list` at that point.

The design is deliberately minimal. There is no nesting, no glob syntax, and no permission level attached to a root. A single `uri` + optional `name` tuple keeps parsing trivial and the protocol transport lightweight. This simplicity is intentional: the spec explicitly frames roots as advisory hints, not an access-control layer. The host process owns enforcement; the server is only expected to be a good citizen and stay within the hinted scope.

When to use

Whenever the client wants to scope server access to specific paths.

When NOT to use

As a security mechanism — use sandboxing or process isolation.

Notes

Roots are advisory, not a security boundary

Servers that read `uri` and use it as a trust perimeter are misconfigured. A malicious or buggy server can ignore roots entirely and attempt to access any path it has OS-level permission to reach. The host process — via OS sandboxing, chroot, or virtual filesystem — is the correct enforcement layer. Never rely on a server honouring roots for confidentiality or integrity guarantees.

URI scheme is not restricted to file://

The spec allows any URI scheme in `uri`, so clients can expose `workspace://`, `git://`, or custom schemes to servers that understand them. In practice, nearly all deployed clients today send `file://` paths. Servers that only understand `file://` should silently skip roots with unrecognised schemes rather than erroring, because clients are free to mix schemes in one session.

Cache roots; do not re-fetch on every request

The `roots/list` round-trip adds latency and the response is stable between `notifications/roots/list_changed` events. Production servers should fetch once post-initialize, store the list in session state, and invalidate only on the change notification. Fetching roots inside a hot tool call path is a common early implementation mistake that shows up as measurable p99 latency spikes.

listChanged capability must be declared before emitting the notification

Clients that send `notifications/roots/list_changed` without advertising `roots: { listChanged: true }` in their `ClientCapabilities` violate the protocol. Servers are entitled to ignore or log-and-discard that notification if the capability was absent during `initialize`. When writing a client, always mirror the `listChanged` flag in `ClientCapabilities.roots` when you plan to emit the notification.

name field affects UX, not routing

The optional `name` string is purely presentational — IDEs pass the project name here so servers can surface it in progress messages or resource titles. It has no semantic role in URI matching or scope calculations. Some SDK wrappers default to the last path segment of `uri` when `name` is omitted, which is fine for display but you should not parse `name` to reconstruct the path.

Fields

Field Type Required Purpose
uri string yes Root URI (often file:// or a custom scheme).
name string? no Friendly label.

Examples

Workspace root

json
{ "uri": "file:///Users/alice/projects/myapp", "name": "myapp" }

Common mistakes

❌ Relying on roots for security

✅ Roots are advisory — enforce boundaries in the host process.

Root FAQ

What is Root in the MCP protocol?

Root is an MCP interface type that defines the structure of protocol data exchanged between MCP clients and servers. It is part of the Model Context Protocol's JSON-RPC 2.0 message schema.

Which package provides the Root type?

Root is defined in the modelcontextprotocol/types package of the MCP TypeScript SDK. Equivalent types are available in the Python, Kotlin, Go, Ruby, and C# SDK implementations.

When should I use Root in my MCP implementation?

Use Root when your MCP host, client, or server implementation needs to work with this protocol structure. Refer to the When to use section above and the MCP specification for authoritative guidance.

What fields does Root contain?

See the Fields table on this page for a complete list of fields in Root, their types, whether they are required or optional, and their purpose.

Where can I find more MCP interface documentation?

The complete MCP API reference on DevShelfHub documents all MCP interfaces, methods, and notifications. Visit the MCP API Reference index to browse all types.