Problem: Claude Desktop Can't Touch Your Files or Browser by Default
Out of the box, Claude Desktop is a chat window. It can't read a file from your hard drive, list a directory, or check what's open in your browser. You have to copy-paste everything manually.
Model Context Protocol (MCP) fixes this. Two official MCP servers — @modelcontextprotocol/server-filesystem and @modelcontextprotocol/server-puppeteer — give Claude direct, sandboxed access to your local file system and a headless browser.
You'll learn:
- How to configure the filesystem MCP server so Claude can read and write files in approved directories
- How to add the Puppeteer MCP server so Claude can navigate URLs and extract page content
- How to verify both connections and combine them in a real workflow
Time: 20 min | Difficulty: Intermediate
Why This Works the Way It Does
MCP is a JSON-RPC protocol that runs a local server process alongside Claude Desktop. Claude Desktop spawns each server as a child process over stdio, so nothing is exposed to the network. When you ask Claude to "read ~/projects/notes.md", it calls the filesystem server's read_file tool — not your OS directly.
Permissions are explicit: you list exactly which directories the filesystem server can touch. The server refuses requests outside those paths. This is not a sandbox in the OS sense — it's enforced by the server's own allowlist logic.
Symptoms of a missing MCP setup:
- Claude says "I can't access local files" when you paste a file path
- No 🔌 (plug) icon in the Claude Desktop toolbar
claude_desktop_config.jsoneither doesn't exist or has nomcpServerskey
Solution
Step 1: Confirm Claude Desktop and Node.js Are Installed
MCP servers for filesystem and browser are Node.js packages. You need Node 20+ and Claude Desktop 0.7+.
# Check versions
node --version # must be v20.0.0 or higher
npm --version # must be 10.x or higher
Download Claude Desktop from claude.ai/download if you haven't already. The MCP config file won't exist until Claude Desktop has been launched at least once.
Expected output:
v22.3.0
10.8.1
If Node is missing or old:
# macOS — install via Homebrew
brew install node
# Ubuntu / Debian
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y nodejs
Step 2: Locate the Claude Desktop Config File
Claude Desktop reads MCP server definitions from a single JSON file.
# macOS
open ~/Library/Application\ Support/Claude/
# Windows (PowerShell)
explorer $env:APPDATA\Claude\
# Linux
xdg-open ~/.config/Claude/
The file you want is claude_desktop_config.json. If it doesn't exist yet, create it:
# macOS / Linux
touch ~/Library/Application\ Support/Claude/claude_desktop_config.json
# or Linux path:
touch ~/.config/Claude/claude_desktop_config.json
Step 3: Add the Filesystem MCP Server
Open claude_desktop_config.json in any editor and add the following. Replace the paths under args with directories you actually want Claude to access.
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/yourname/projects",
"/Users/yourname/Documents/notes"
]
}
}
}
What each part does:
"command": "npx"— Claude Desktop spawnsnpxas the server process"-y"— auto-installs the package on first run without prompting- The path arguments after the package name are the allowlisted directories. Add as many as you need. Claude cannot read or write outside these paths.
Windows path format:
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"C:\\Users\\yourname\\projects"
]
If it fails:
Error: ENOENT: no such file or directory→ The path you listed doesn't exist. Create it first or fix the typo.spawn npx ENOENT→ Node.js is not on the PATH that Claude Desktop uses. On macOS, add"env": { "PATH": "/usr/local/bin:/opt/homebrew/bin:/usr/bin" }to the server config object.
Step 4: Add the Puppeteer (Browser) MCP Server
Append a second entry to mcpServers. The full config now looks like this:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/yourname/projects",
"/Users/yourname/Documents/notes"
]
},
"puppeteer": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-puppeteer"
]
}
}
}
The Puppeteer server launches a headless Chromium instance on demand. It exposes tools like puppeteer_navigate, puppeteer_screenshot, and puppeteer_get_content that Claude can call to fetch and parse web pages.
First-run note: @modelcontextprotocol/server-puppeteer downloads Chromium (~170MB) on its first invocation. This happens once, then it's cached in ~/.cache/puppeteer.
If it fails:
Error: Failed to launch the browser process→ Missing system deps on Linux. Run:sudo apt-get install -y libatk-bridge2.0-0 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxrandr2 libgbm1 libasound2- Timeout on first run → Chromium is downloading. Wait 2–3 minutes and retry.
Step 5: Restart Claude Desktop
MCP servers are launched at startup. Config changes don't apply until you fully quit and reopen Claude Desktop.
# macOS — force quit then reopen
osascript -e 'quit app "Claude"'
open -a Claude
# Windows
# Right-click Claude in taskbar → Quit → reopen from Start menu
After restart, look for the 🔌 plug icon in the bottom-left of the Claude Desktop input area. Clicking it shows connected servers and their available tools.
Verification
Test the filesystem server — ask Claude directly in the chat:
List the files in /Users/yourname/projects and show me the first 20 lines of any README you find.
You should see: Claude call list_directory and then read_file, with results displayed inline. No copy-pasting needed.
Test the browser server:
Navigate to https://example.com and tell me the page title and main heading.
You should see: Claude call puppeteer_navigate followed by puppeteer_get_content, then summarize the page.
Test a combined workflow:
Fetch the changelog from https://ollama.com/blog and save a summary to /Users/yourname/projects/ollama-changelog-notes.md
Claude will browse the URL, extract content, and write the file — chaining both servers in one request.
What You Learned
- MCP servers run as local child processes over stdio — no external network exposure
- The filesystem server enforces its own path allowlist; add only directories you want Claude to touch
- Puppeteer gives Claude a real headless browser, not just an HTTP fetch — it handles JavaScript-rendered pages
- Both servers install on first
npxinvocation; no global install step needed
Limitation: The filesystem server has no write-confirmation prompt. Claude will write or overwrite files immediately when asked. If you're nervous about that, start with a dedicated scratch directory in your allowlist until you're comfortable with the workflow.
When NOT to use this: Don't add sensitive directories (SSH keys, .env files, credential stores) to the filesystem allowlist. MCP gives Claude real write access — treat it like giving a junior developer access to those folders.
Tested on Claude Desktop 0.7.5, Node.js 22.3.0, @modelcontextprotocol/server-filesystem 0.6.2, @modelcontextprotocol/server-puppeteer 0.5.1, macOS 15 Sequoia and Ubuntu 24.04