MCP with Claude Desktop: File System and Browser Access

Connect Claude Desktop to your local file system and browser via MCP servers. Read, write, and browse in under 20 minutes.

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.json either doesn't exist or has no mcpServers key

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 spawns npx as 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 npx invocation; 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