How to Use MCP Roots to Give Claude Controlled Access to Your Projects

Learn how to use MCP Roots to give Claude focused, safe access to exactly the files and folders it needs — nothing more.

The Problem With Giving AI "Full Access"

When I first started using MCP file system tools with Claude, my instinct was to just... point it at everything. Like, here's my whole home directory, knock yourself out. It felt powerful. It also felt kind of terrifying the moment I realized Claude could technically browse through years of random files I'd completely forgotten about.

That's where MCP Roots come in. Roots are one of those features that sounds technical but is actually just a really sensible idea: instead of giving Claude access to your entire machine, you tell it exactly which folders it's allowed to work inside. Think of it like handing a contractor a key to one room instead of the whole building.

In this post I'll show you what Roots are, how to set them up, and why they'll actually make your AI workflow better — not just safer.

What Are MCP Roots, Exactly?

In the MCP (Model Context Protocol) spec, a "Root" is a URI — basically a file path — that you declare as a boundary for Claude's access. When your MCP server advertises roots, it's saying: "Hey Claude, here are the directories you're allowed to read and write inside. Stay in these lanes."

Roots show up in your MCP server configuration, and Claude-compatible clients (like Claude Desktop) respect them automatically. The client passes the list of roots to the server when the session starts, and the server uses that to scope its operations.

The practical result: Claude can help you with your /projects/my-app folder without being able to wander off into /Users/dan/Documents/taxes-2019. Which, trust me, is a good thing.

Roots vs. File System Permissions

Roots are a hint at the application layer — they tell Claude where to focus, but they're not a replacement for your OS-level file permissions. Think of them as guardrails for the AI, not a security wall. Your actual file permissions still apply underneath.

Setting Up Roots in Your MCP Config

If you're using Claude Desktop, your MCP servers are configured in a JSON file. On a Mac that lives at ~/Library/Application Support/Claude/claude_desktop_config.json. On Windows it's in your AppData folder.

Here's what a basic filesystem MCP server config looks like without roots — the kind that gives Claude broad access:

claude_desktop_config.json
// Basic setup — no roots scoping
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/dan"
]
}
}
}

Now here's the same config but scoped to specific project roots. Instead of handing Claude your entire home directory, you pass only the folders that matter for the work you're doing:

claude_desktop_config.json
// Scoped to two specific project roots
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/dan/projects/my-app",
"/Users/dan/projects/my-app-docs"
]
}
}
}

Each path you pass as an argument becomes a root. Claude can read and write files inside those folders. It can't touch anything outside them. Clean, simple, and way less anxiety-inducing.

Why Scoped Roots Actually Make Claude More Useful

Here's something I didn't expect: limiting Claude's access made it better at helping me, not worse. When I pointed it at my entire home directory, it would sometimes get confused about which files were relevant. There's a lot of noise in a full file system — old downloads, random scripts, config files from tools I don't even use anymore.

When I scoped it to just the project I was working on, Claude's responses got sharper. It wasn't guessing which config.json I meant. It knew, because there was only one in scope.

Think of it like context windows — the more focused the input, the more focused the output. Roots give Claude a clean mental model of "where we are" for this conversation.

Pro tip: Match your roots to your project

I keep a few different config presets saved and swap them out depending on what I'm working on. One for my main web app, one for side projects, one for writing. It takes 30 seconds to update the config and restart Claude Desktop.

A Real Example: Working on a Side Project

Let me walk through how I actually use this. Say I'm working on a small Python side project — a CLI tool I've been building to automate some repetitive tasks. The project lives at /Users/dan/projects/cli-tool and I also have some shared utility scripts at /Users/dan/projects/shared-utils that I reference.

I set my roots to both of those folders:

config
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/dan/projects/cli-tool",
"/Users/dan/projects/shared-utils"
]

Now I can open Claude Desktop and say: "Read through my main.py and the helpers in shared-utils, then tell me where the error handling is inconsistent." Claude can actually do that — it has access to both folders, and only those folders. It reads the files, compares them, and gives me a real answer instead of making something up.

When I switch to a different project the next day, I just update the paths and restart. Takes maybe a minute.

Verifying Claude Respects Your Roots

Honestly, when I first set this up I was a little skeptical. Does Claude actually stay within the roots, or is that just aspirational? Here's a quick way to test it yourself.

After setting your roots, try asking Claude to read a file you know is outside those paths:

test prompt
# Ask Claude to read something outside your roots
"Can you read the file at /Users/dan/Documents/notes.txt?"

→ Claude should report it cannot access that path
→ or the MCP server returns a permission error

If the server is configured correctly, you'll get an error — something like "path is outside allowed directories." That's exactly what you want to see. It means your roots are working as intended.

Always restart Claude Desktop after changing your config

MCP servers spin up when Claude Desktop launches. If you edit your config file, you need to fully quit and reopen the app for the new roots to take effect. A lot of head-scratching can be avoided by remembering this one thing.

Common Mistakes to Avoid

I made all of these, so you don't have to:

Using relative paths. Always use full absolute paths in your roots config. Relative paths like ./projects/my-app won't work reliably because the MCP server doesn't know what directory to resolve them from. Write out the full thing starting from /Users/yourname/...

Setting a root too high up the tree. If you set your root to /Users/dan/projects thinking "well that covers all my projects," you've basically given Claude access to everything in there. That might be fine, but it's worth being intentional about it rather than accidental.

Forgetting to add a second root when you need it. I once spent 10 minutes wondering why Claude couldn't read a file before realizing I'd only put one path in the config and the file I needed was in a different folder. Add all the roots you need upfront.

Not restarting Claude Desktop. I know I already said this. I'm saying it again because I've done it three times.

Start Small and Expand

My recommendation: start with a single root pointed at one real project you're working on right now. Get comfortable with how it feels to have Claude actually reading and understanding your actual files. Then, if you find yourself needing access to something else, add it.

The goal isn't to lock Claude down so hard it can't help you. The goal is intentionality — knowing exactly what Claude can see and why. That makes you a better AI collaborator, and honestly it makes the whole thing feel less like handing over the keys to your life and more like a productive working relationship.

Once you've got roots humming along, you're in a great position to explore more advanced MCP features — like combining the filesystem server with other MCP servers (say, a database server) in the same config. But that's a topic for another day. For now, go set your first root and see how much cleaner the experience gets.

Keep going

More tutorials in this category, or explore the full field guide.

More Plugin Tutorials Official Docs ↗