All Posts

How to Set Up MCP Servers in Claude Desktop (Complete Guide)

Claude Desktop becomes dramatically more useful the moment you connect it to external tools through MCP servers. Instead of copying data in and out of conversations, Claude can directly query your CRM, pull enrichment data, search the web, and interact with your file system--all from within the

How to Set Up MCP Servers in Claude Desktop (Complete Guide)

Published on
February 26, 2026

Overview

Claude Desktop becomes dramatically more useful the moment you connect it to external tools through MCP servers. Instead of copying data in and out of conversations, Claude can directly query your CRM, pull enrichment data, search the web, and interact with your file system--all from within the chat interface.

The setup process isn't complicated, but the documentation is scattered and the error messages are unhelpful. A misplaced comma in your config file means silent failure. A missing environment variable means a cryptic crash. This guide consolidates everything you need to configure MCP servers in Claude Desktop correctly the first time--from locating the config file to wiring up multiple servers for real GTM engineering workflows.

If you're new to MCP as a concept, start with our MCP guide for GTM teams. This article assumes you understand what MCP does and want to get servers running in Claude Desktop specifically.

Finding the Claude Desktop Configuration File

Claude Desktop reads MCP server definitions from a single JSON file. The file path varies by operating system, and it doesn't exist by default--you'll need to create it.

Operating System Configuration File Path
macOS ~/Library/Application Support/Claude/claude_desktop_config.json
Windows %APPDATA%\Claude\claude_desktop_config.json
Linux ~/.config/Claude/claude_desktop_config.json

Creating the Config File

On macOS, open Terminal and run:

# Check if the directory exists
ls ~/Library/Application\ Support/Claude/

# If it doesn't exist, create it
mkdir -p ~/Library/Application\ Support/Claude/

# Create or open the config file
open -a TextEdit ~/Library/Application\ Support/Claude/claude_desktop_config.json

On Windows, open PowerShell:

# Navigate to the directory
cd $env:APPDATA\Claude

# Create the config file if it doesn't exist
if (!(Test-Path "claude_desktop_config.json")) {
    New-Item -ItemType File -Name "claude_desktop_config.json"
}

# Open in Notepad
notepad claude_desktop_config.json

If the file is empty or doesn't exist yet, start with this minimal structure:

{
  "mcpServers": {}
}
Quick Access on macOS

You can also reach the config file through Claude Desktop itself: open the app, go to Settings (Claude menu > Settings), then click "Developer" in the sidebar. There's an "Edit Config" button that opens the file directly.

Understanding the MCP Server JSON Configuration

Every MCP server in Claude Desktop is defined as an entry in the mcpServers object. Each entry tells Claude how to launch the server process, what arguments to pass, and what environment variables to set.

Configuration Structure

{
  "mcpServers": {
    "server-name": {
      "command": "executable",
      "args": ["argument1", "argument2"],
      "env": {
        "API_KEY": "your-key-here",
        "OTHER_VAR": "value"
      }
    }
  }
}

Here's what each field does:

Field Required Description
command Yes The executable to run. Common values: npx, node, python, python3, uvx
args Yes Array of arguments passed to the command. For npx packages, this includes the package name and any server-specific arguments.
env No Object of environment variables the server process needs. Used for API keys, connection strings, and configuration flags.

How Claude Desktop Launches Servers

When Claude Desktop starts (or restarts), it reads the config file and spawns each server as a child process. Communication happens over stdio--the server reads JSON-RPC messages from stdin and writes responses to stdout. This means:

  • Servers run as long as Claude Desktop is open
  • You don't need to keep a terminal window running
  • Each server is an isolated process with its own memory and credentials
  • A crash in one server doesn't affect others
Important: Restart Required

Claude Desktop only reads the config file at launch. After any change to claude_desktop_config.json, you must fully quit and reopen Claude Desktop. On macOS, make sure to quit from the menu bar icon too--just closing the window doesn't stop the app.

A Complete Single-Server Example

Here's a real working configuration for the filesystem server, which gives Claude read and write access to specific directories on your machine:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/yourname/projects",
        "/Users/yourname/Documents/gtm-playbooks"
      ]
    }
  }
}

The -y flag tells npx to auto-confirm package installation. The paths after the package name are directories the server is allowed to access. Claude can read and write files only within those directories.

Environment Variable Handling

Most MCP servers that connect to external APIs need credentials. The env field in your config is how you pass these to the server process. This is straightforward, but there are several patterns worth understanding--especially if you're managing credentials for multiple GTM tools.

Inline Environment Variables

The simplest approach: put credentials directly in the config file.

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxxxxxxxxxxxxxx"
      }
    }
  }
}

This works for personal use. The downside is obvious: credentials are stored in plaintext on disk. If you share this config or commit it to version control, your keys are exposed.

Referencing System Environment Variables

Claude Desktop's env field sets environment variables for the server process, but the config file itself is static JSON--it doesn't expand $HOME or %USERPROFILE%. If you want to use system environment variables, you have two options:

Option 1: Set variables in your shell profile and use absolute paths to executables. Claude Desktop inherits some system environment variables (varies by OS and how you launch the app). This isn't reliable enough for credentials.

Option 2: Use a wrapper script. Create a small shell script that loads your secrets and then launches the server:

#!/bin/bash
# ~/scripts/launch-crm-server.sh
source ~/.secrets/gtm-credentials.env
exec python3 /path/to/crm-server.py

Then reference the wrapper in your config:

{
  "mcpServers": {
    "crm": {
      "command": "/Users/yourname/scripts/launch-crm-server.sh",
      "args": []
    }
  }
}

Common Environment Variables by Server Type

Server Required Variables Where to Get Them
GitHub GITHUB_PERSONAL_ACCESS_TOKEN GitHub Settings > Developer Settings > Personal Access Tokens
Brave Search BRAVE_API_KEY brave.com/search/api
Slack SLACK_BOT_TOKEN, SLACK_TEAM_ID api.slack.com > Your Apps > OAuth & Permissions
PostgreSQL Connection string in args Your database hosting provider
Custom CRM Server SALESFORCE_TOKEN, HUBSPOT_API_KEY, etc. CRM admin settings > API access
Security Warning

Never commit claude_desktop_config.json to version control if it contains API keys. Add it to your .gitignore. For team setups, distribute a template config with placeholder values and let each person fill in their own credentials. Use the minimum permission scope your server actually needs--a read-only CRM token is better than an admin token if you only need to query data.

Setting Up Multiple MCP Servers

A single MCP server is useful. Multiple servers working together is where Claude Desktop becomes a serious GTM engineering tool. You can run as many servers simultaneously as your system can handle, and Claude has access to tools from all of them in every conversation.

Multi-Server Configuration

Just add more entries to the mcpServers object. Each key must be unique:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/yourname/projects/gtm-playbooks"
      ]
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxxxxxx"
      }
    },
    "brave-search": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-brave-search"],
      "env": {
        "BRAVE_API_KEY": "BSA_xxxxxxxxxxxx"
      }
    },
    "postgres": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-postgres",
        "postgresql://user:pass@localhost:5432/gtm_data"
      ]
    }
  }
}

How Claude Handles Multiple Servers

When multiple servers are configured, Claude Desktop:

  • Launches all servers at startup
  • Aggregates tools from every server into a single tool palette
  • Shows all available tools when you click the hammer icon
  • Automatically selects the right server's tools based on your request

This means you can ask Claude something like "Look up acme.com on GitHub, search for their latest news, and check if they're in our database"--and Claude will use tools from three different servers in a single response.

Naming Conventions

Server keys are identifiers, not display names. Use clear, lowercase, hyphenated names that describe what the server connects to:

  • crm-readonly vs. crm-admin (differentiating permission levels)
  • enrichment-clearbit vs. enrichment-clay (differentiating providers)
  • filesystem-projects vs. filesystem-docs (differentiating access scopes)

Avoid generic names like server1 or test. When you have six servers running, clear names save debugging time.

Performance Consideration

Each MCP server is a separate process consuming memory. Most servers are lightweight (10-50MB), but database servers with persistent connections or servers that cache data locally can use more. If you notice Claude Desktop becoming sluggish, check Activity Monitor (macOS) or Task Manager (Windows) for runaway MCP processes.

GTM Server Examples: CRM, Enrichment, and More

The official MCP server registry covers general-purpose tools, but GTM workflows demand specific integrations. Here are configurations for the servers that GTM engineers actually use.

CRM Access Servers

Connecting Claude to your CRM data means it can look up accounts, review deal history, and pull contact details without you exporting CSVs or pasting records into the chat.

Custom Salesforce Server (Python):

{
  "mcpServers": {
    "salesforce": {
      "command": "python3",
      "args": ["/Users/yourname/mcp-servers/salesforce-server.py"],
      "env": {
        "SF_INSTANCE_URL": "https://yourorg.my.salesforce.com",
        "SF_ACCESS_TOKEN": "your-oauth-token",
        "SF_API_VERSION": "v59.0"
      }
    }
  }
}

A well-built CRM server exposes tools like search_accounts, get_contact, get_deal_pipeline, and log_activity. This lets Claude answer questions like "What's our pipeline with Acme Corp?" or "When did we last contact the VP of Engineering at DataCo?" directly from your CRM data.

HubSpot Server:

{
  "mcpServers": {
    "hubspot": {
      "command": "npx",
      "args": ["-y", "hubspot-mcp-server"],
      "env": {
        "HUBSPOT_ACCESS_TOKEN": "pat-xxxxxxxxxxxx"
      }
    }
  }
}

Data Enrichment Servers

Enrichment servers let Claude pull firmographic, technographic, and intent data on demand--turning it into a real-time research agent.

Brave Search (for web research):

{
  "mcpServers": {
    "brave-search": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-brave-search"],
      "env": {
        "BRAVE_API_KEY": "BSA_xxxxxxxxxxxx"
      }
    }
  }
}

Custom Enrichment Aggregator:

{
  "mcpServers": {
    "enrichment": {
      "command": "python3",
      "args": ["/Users/yourname/mcp-servers/enrichment-aggregator.py"],
      "env": {
        "CLEARBIT_API_KEY": "sk_xxxxxxxxxxxx",
        "APOLLO_API_KEY": "xxxxxxxxxxxx"
      }
    }
  }
}

An enrichment aggregator server is especially powerful because it can query multiple providers behind a single tool interface. Instead of Claude making separate calls to Clearbit and Apollo, your server handles the waterfall enrichment logic and returns merged results.

Database Servers for Pipeline Analytics

If your team maintains a data warehouse with pipeline and engagement data, a database server turns Claude into an analyst:

{
  "mcpServers": {
    "analytics-db": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-postgres",
        "postgresql://readonly_user:password@analytics-db.internal:5432/gtm_warehouse"
      ]
    }
  }
}

You can ask Claude to query conversion rates, analyze sequence performance, or identify which account signals correlate with closed deals. It translates natural language into SQL and returns structured results.

Use Read-Only Credentials

For database and CRM servers, always use read-only credentials unless you specifically need write access. A misunderstood prompt shouldn't result in Claude updating 500 CRM records. Create dedicated API users with the minimum permissions your workflow requires.

Full GTM Stack Configuration

Here's what a complete configuration looks like for a GTM engineer who wants Claude to access their files, CRM, enrichment data, and web search:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/yourname/projects/playbooks",
        "/Users/yourname/projects/sequences"
      ]
    },
    "salesforce": {
      "command": "python3",
      "args": ["/Users/yourname/mcp-servers/sf-server.py"],
      "env": {
        "SF_INSTANCE_URL": "https://yourorg.my.salesforce.com",
        "SF_ACCESS_TOKEN": "your-token"
      }
    },
    "enrichment": {
      "command": "python3",
      "args": ["/Users/yourname/mcp-servers/enrichment-server.py"],
      "env": {
        "CLEARBIT_API_KEY": "sk_xxxxxxxxxxxx"
      }
    },
    "brave-search": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-brave-search"],
      "env": {
        "BRAVE_API_KEY": "BSA_xxxxxxxxxxxx"
      }
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxxxxxx"
      }
    }
  }
}

With this setup, a single Claude conversation can: search the web for company news, enrich the company with firmographic data, check CRM history, review your playbook files, and draft a personalized outreach sequence--all without you leaving the chat interface.

Debugging MCP Connection Issues

MCP setup fails silently more often than it fails loudly. Here's a systematic approach to diagnosing and fixing the most common problems.

Step 1: Verify JSON Syntax

A single syntax error in your config file breaks all servers, not just the one with the error. Before restarting Claude Desktop, validate your JSON:

# macOS/Linux: Use jq to validate
cat ~/Library/Application\ Support/Claude/claude_desktop_config.json | jq .

# If the JSON is invalid, jq will show exactly where the error is
# Common mistakes:
# - Trailing comma after the last server entry
# - Missing quotes around keys or values
# - Using single quotes instead of double quotes

If you don't have jq installed, paste your config into any online JSON validator. Fix syntax errors before trying anything else.

Step 2: Check Server Visibility

After restarting Claude Desktop, click the hammer icon (tool palette) at the bottom of a new conversation. You should see tools listed from each configured server. If the hammer icon doesn't appear at all or shows no tools:

  • The config file isn't in the right location
  • The JSON is invalid
  • The server failed to start

Step 3: Read the Logs

Claude Desktop logs MCP-related errors. The log locations:

OS Log Location
macOS ~/Library/Logs/Claude/mcp*.log
Windows %APPDATA%\Claude\logs\
Linux ~/.config/Claude/logs/

You can also use macOS Console.app and filter for "Claude" to see real-time log output. Look for messages about server initialization failures, connection timeouts, or missing dependencies.

Step 4: Test the Server Manually

Run the exact command from your config in a terminal to see if the server starts independently:

# Test an npx-based server
npx -y @modelcontextprotocol/server-filesystem /Users/yourname/projects

# Test a Python server
SALESFORCE_TOKEN=your-token python3 /path/to/server.py

If the server fails in your terminal, it will fail in Claude Desktop too. Common errors at this stage:

  • Package not found: The npm package name is wrong or your Node.js version is too old
  • Python module not found: The MCP SDK isn't installed in the Python environment Claude Desktop uses
  • Permission denied: The executable path isn't correct or lacks execute permissions

Step 5: Use the MCP Inspector

The MCP Inspector is a browser-based debugging tool that lets you interact with servers directly, bypassing Claude entirely:

# Install and run
npx @modelcontextprotocol/inspector

# Or point it at a specific server
npx @modelcontextprotocol/inspector npx -y @modelcontextprotocol/server-filesystem /tmp

The Inspector shows you the raw JSON-RPC messages, all registered tools and resources, and lets you invoke tools with custom parameters. If something works in the Inspector but not in Claude Desktop, the issue is with the config file or Claude Desktop itself, not your server.

Common Failure Patterns

Symptom Cause Fix
No hammer icon appears Config file in wrong location or invalid JSON Verify file path and validate JSON syntax
Hammer icon shows but no tools listed Server crashed during startup Check logs; test server manually in terminal
Tools appear but calls fail Missing or invalid API credentials Verify env variables are correct; check API key permissions
Server works in terminal but not in Claude PATH or environment mismatch Use absolute paths for commands; set all env vars explicitly
"Server disconnected" mid-conversation Unhandled exception crashed the process Check server logs; add error handling to custom servers
Extremely slow tool responses Synchronous API calls blocking the event loop Use async HTTP clients (httpx for Python, fetch for Node.js)
The Absolute Path Fix

The single most common issue is Claude Desktop not finding executables because it doesn't inherit your shell's PATH. Instead of "command": "python", use the full path: "command": "/usr/local/bin/python3". Find the absolute path by running which python3 or which npx in your terminal.

Advanced Configuration Patterns

Once you have basic servers running, these patterns help you build more robust setups for daily use.

Using uvx for Python Servers

If you use uv (the fast Python package manager), uvx provides a cleaner way to run Python-based MCP servers without managing virtual environments:

{
  "mcpServers": {
    "custom-server": {
      "command": "uvx",
      "args": ["--from", "your-mcp-package", "server-entrypoint"],
      "env": {
        "API_KEY": "your-key"
      }
    }
  }
}

uvx automatically handles dependency isolation, similar to how npx works for Node.js packages. It's the cleanest option for Python servers that are distributed as packages.

Custom Servers from Local Scripts

You don't need to publish an npm or PyPI package to run a custom MCP server. Point directly to a local script:

{
  "mcpServers": {
    "my-gtm-tools": {
      "command": "/usr/local/bin/python3",
      "args": ["/Users/yourname/mcp-servers/gtm-tools/server.py"],
      "env": {
        "CRM_TOKEN": "your-token",
        "ENRICHMENT_KEY": "your-key"
      }
    }
  }
}

This is the typical pattern for building custom servers that wrap your specific GTM data sources. Start with a local script, iterate until the tools work well, then optionally package it for distribution. Our MCP server tutorial walks through building these from scratch.

Splitting Read and Write Access

For sensitive systems, run two instances of the same server with different permission levels:

{
  "mcpServers": {
    "crm-reader": {
      "command": "python3",
      "args": ["/path/to/crm-server.py", "--mode", "readonly"],
      "env": {
        "SF_TOKEN": "readonly-token"
      }
    },
    "crm-writer": {
      "command": "python3",
      "args": ["/path/to/crm-server.py", "--mode", "readwrite"],
      "env": {
        "SF_TOKEN": "admin-token"
      }
    }
  }
}

The read-only instance is safe for exploratory queries. The read-write instance is available when you explicitly need to update records. Your server code handles the mode flag and exposes different tool sets accordingly.

Conditional Server Loading

Claude Desktop doesn't support conditional logic in the config file. If you want to enable servers based on context (e.g., only load the staging CRM server during testing), the simplest approach is to maintain multiple config files and swap them:

# Keep different configs
~/configs/claude-desktop-production.json
~/configs/claude-desktop-development.json

# Swap with a symlink (macOS/Linux)
ln -sf ~/configs/claude-desktop-production.json \
  ~/Library/Application\ Support/Claude/claude_desktop_config.json

Or use a script that merges configs based on environment flags. It's extra setup, but teams managing multiple environments find it worthwhile.

FAQ

Can I add MCP servers without restarting Claude Desktop?

No. Claude Desktop reads the configuration file only at startup. Any changes require a full restart--quit the application completely (including from the menu bar or system tray) and reopen it.

Is there a limit to how many MCP servers I can run?

There's no hard limit in the protocol or Claude Desktop. Practically, each server is a separate process consuming memory and potentially a network connection. Most users run 3-8 servers without issues. If you're running 15+ servers, consider consolidating related functionality into fewer servers.

Can two MCP servers expose tools with the same name?

Technically yes, but it creates ambiguity. Claude may pick the wrong server's tool. Use distinct, descriptive tool names. If you have two servers that both expose a "search" tool, rename them to "search_crm" and "search_enrichment" in their respective implementations.

Do MCP servers have access to my Claude conversations?

No. MCP servers only receive the specific tool calls Claude sends them. They don't see your conversation history, other tool calls, or any data outside what their tools are explicitly asked to retrieve or process.

Why does my server work in the terminal but not in Claude Desktop?

The most common cause is environment differences. Claude Desktop doesn't inherit your shell profile (e.g., .bashrc, .zshrc). Use absolute paths for executables (/usr/local/bin/python3 instead of python3) and explicitly set all required environment variables in the config's env block.

Can I use the same MCP server config in Claude Desktop and Claude Code?

The JSON format is identical. Claude Code uses a .mcp.json file in your project root or the claude mcp add CLI command. You can copy server entries between configs directly. The main difference is scope: Claude Desktop configs are global, while Claude Code configs can be per-project.

How do I update an MCP server to a newer version?

For npx-based servers, the -y flag auto-installs the latest version each time Claude Desktop restarts. To force a specific version, include it in the args: "args": ["-y", "@modelcontextprotocol/server-filesystem@1.2.0"]. For local scripts, update the code and restart Claude Desktop.

From Individual Tools to Unified Context

Setting up MCP servers in Claude Desktop is a strong starting point. You get direct access to your CRM, enrichment APIs, and files--all within the same conversation. For individual research sessions and ad-hoc workflows, it's a genuine productivity upgrade.

But notice the pattern that emerges as your setup matures. You configure a CRM server, an enrichment server, a search server, and a database server. Each one connects Claude to a single data source. When you want to research a prospect, Claude orchestrates multiple tool calls across multiple servers, assembling context on the fly. That works for one-off queries. It breaks down in several ways at scale.

First, there's no shared state across conversations. The research Claude did yesterday about Acme Corp is gone today. Second, every team member maintains their own config with their own credentials and their own subset of tools. Your enrichment server might differ from your colleague's. Third, the AI has to re-assemble context from scratch for every request--querying the CRM, then enrichment, then signals, then engagement history--even for accounts your team has researched dozens of times.

What you actually need at that point is a context layer that pre-unifies all of this data: firmographics, CRM records, engagement signals, and fit scores assembled into a persistent graph that any AI tool can query without reassembling the picture from five separate API calls.

This is what platforms like Octave are designed for. Instead of each team member maintaining local MCP server configs that fragment context across individual machines, Octave maintains a unified GTM context layer that includes enrichment, CRM data, scoring, and interaction history. The individual connections to your tools still exist, but they feed a shared, continuously updated context graph rather than serving one-off queries in isolated Claude Desktop sessions. For teams operationalizing AI-powered outbound at scale, it's the difference between prototyping on your laptop and running infrastructure that your whole team relies on.

Conclusion

MCP server setup in Claude Desktop comes down to one JSON file with a predictable structure. Locate the config, define your servers with the right commands and environment variables, restart the app, and verify the tools appear. When something breaks, validate JSON syntax first, check logs second, and test the server in your terminal third.

Start with the filesystem server to confirm your setup works, then add one API-connected server that solves a real problem--CRM lookups, web research, or database queries. Resist the urge to configure everything at once. Each working server you add compounds Claude's usefulness, turning it from a chat interface into a connected GTM tool.

The configuration patterns in this guide apply whether you're running one server or ten. Get the basics right--absolute paths, explicit environment variables, valid JSON--and you'll spend your time using the tools instead of debugging them.

FAQ

Frequently Asked Questions

Still have questions? Get connected to our support team.