Roots inform servers about filesystem resources the client has access to. Servers can use this information to adjust behavior or restrict operations to safe boundaries.
from pathlib import Path
from dedalus_mcp.client import ClientCapabilitiesConfig, open_connection
from dedalus_mcp.types import Root
initial_roots = [
Root(uri=Path.cwd().as_uri(), name="Project Directory"),
Root(uri=Path("/tmp").as_uri(), name="Temporary Files"),
]
capabilities = ClientCapabilitiesConfig(
enable_roots=True,
initial_roots=initial_roots,
)
async with open_connection(
url="http://127.0.0.1:8000/mcp",
transport="streamable-http",
capabilities=capabilities,
) as client:
# List advertised roots
roots = await client.list_roots()
for root in roots:
print(f"{root.name}: {root.uri}")
Dynamic Updates
Update roots during the session:
async with open_connection(
url="http://127.0.0.1:8000/mcp",
transport="streamable-http",
capabilities=capabilities,
) as client:
# Add a new root
new_roots = initial_roots + [
Root(uri=Path.home().as_uri(), name="Home Directory"),
]
await client.update_roots(new_roots, notify=True)
# Verify update
roots = await client.list_roots()
print(f"Now advertising {len(roots)} roots")
Root Structure
from dedalus_mcp.types import Root
Root(
uri="file:///path/to/directory", # File URI
name="Human-readable name", # Optional display name
)
| Field | Type | Description |
|---|
uri | str | File URI (e.g., file:///home/user/project) |
name | str | Optional human-readable name |
Security
Roots establish security boundaries. Servers should:
- Only access files within advertised roots
- Reject operations targeting paths outside root boundaries
- Use roots to scope file searches and operations
# Server-side: check if path is within roots
def is_path_allowed(path: Path, roots: list[Root]) -> bool:
for root in roots:
root_path = Path(str(root.uri).replace("file://", ""))
if path.is_relative_to(root_path):
return True
return False
Last modified on January 27, 2026