Stop your tool from escaping its roots
The MCP SDK does not stop a tool from touching files outside the directories a user granted — that's on you. You'll write is_path_allowed(), which checks a requested path against the client's roots before any file is accessed.
FastMCP and Context are imported and the server mcp is created. check_access(path) runs your function through a real MCP client–server session: the connected client grants one directory (/tmp/mcp_allowed_root, holding video.mp4), and mcp_outside.mp4 sits outside it. root_to_path() converts a root to a Path.
This exercise is part of the course
Model Context Protocol: Advanced Topics
Exercise instructions
- Call
ctx.session.list_roots()to get the directories the server may access. - Return
Truewhen the requested path is inside one of the roots.
Hands-on interactive exercise
Have a go at this exercise by completing this sample code.
async def is_path_allowed(requested_path, ctx):
# Get the client's allowed roots
roots_result = await ctx.session.____()
for root in roots_result.roots:
root_path = root_to_path(root)
try:
requested_path.relative_to(root_path)
# Allow paths inside a root
return ____
except ValueError:
continue
return False
# Check a file inside the allowed root, and one outside it
allowed = check_access("/tmp/mcp_allowed_root/video.mp4")
denied = check_access("/tmp/mcp_outside.mp4")
print(allowed, denied)