# Provide roots

::: warning Deprecated — SEP-2577
Pass paths through tool arguments, resource URIs, or host configuration instead. **Roots** are deprecated as of protocol version 2026-07-28 (SEP-2577) and stay functional on 2025-era connections for at least twelve months — see the [deprecated features registry](https://modelcontextprotocol.io/specification/draft/deprecated).
:::

## Migrate away first

A **root** is a `file://` URI the client hands to the server as a boundary for its file operations. The 2026-07-28 revision deprecates the request that carries them, and nothing replaces it — give the server its paths directly.

Send the path a call should act on as a tool argument ([Tools](https://ts.sdk.modelcontextprotocol.io/v2/servers/tools.md)), expose the locations the server owns as resources ([Resources](https://ts.sdk.modelcontextprotocol.io/v2/servers/resources.md)), or put fixed directories in the server's own configuration. The rest of this page covers the roots API for clients that still answer 2025-era servers through the deprecation window.

## Declare the roots capability

`roots` in the `Client` constructor's `capabilities` tells the server it can ask for the list; `listChanged: true` also lets you notify it when the list changes.

```ts
import { Client } from '@modelcontextprotocol/client';

const client = new Client({ name: 'workspace-client', version: '1.0.0' }, { capabilities: { roots: { listChanged: true } } });
```

Declare the capability before registering the handler: without it, `setRequestHandler('roots/list', …)` throws.

## Answer roots/list

`setRequestHandler('roots/list', …)` returns `{ roots }`. Every `uri` must start with `file://`; `name` is optional.

```ts
const roots = [
    { uri: 'file:///home/user/projects/my-app', name: 'My App' },
    { uri: 'file:///home/user/data', name: 'Data' }
];

client.setRequestHandler('roots/list', async () => {
    return { roots };
});
```

A connected server that requests `roots/list` receives exactly what the handler returned:

```
[
  { uri: 'file:///home/user/projects/my-app', name: 'My App' },
  { uri: 'file:///home/user/data', name: 'Data' }
]
```

Roots are advisory boundaries, not an access grant — the server still reaches the filesystem with its own permissions, and the SDK never enforces the list on either side.

::: info
On a 2026-07-28 connection there is no server-to-client request channel; the same handler fulfils a `roots/list` request embedded in an `input_required` result — see [Protocol versions](https://ts.sdk.modelcontextprotocol.io/v2/protocol-versions.md).
:::

## Tell the server when the roots change

`sendRootsListChanged()` sends `notifications/roots/list_changed`; it requires the `listChanged: true` declared above.

```ts
roots.push({ uri: 'file:///home/user/projects/another-app', name: 'Another app' });
await client.sendRootsListChanged();
```

The notification carries no payload. A server that watches it requests `roots/list` again and receives the updated list:

```
[
  { uri: 'file:///home/user/projects/my-app', name: 'My App' },
  { uri: 'file:///home/user/data', name: 'Data' },
  {
    uri: 'file:///home/user/projects/another-app',
    name: 'Another app'
  }
]
```

## Recap

- Roots are deprecated (SEP-2577): pass paths through tool arguments, resource URIs, or configuration instead.
- `capabilities: { roots: { listChanged: true } }` on the `Client` constructor declares the capability; register the `roots/list` handler only after declaring it.
- The handler returns `{ roots }`, and every root `uri` starts with `file://`.
- Roots are advisory boundaries, not an access grant.
- `sendRootsListChanged()` notifies the server that the list changed; the server re-requests `roots/list` itself.
