Claude Desktop MCP Setup: Config File Location & .mcpb Installation
I spent two hours staring at Claude Desktop wondering why my MCP server wouldn't connect. The config looked perfect. The server ran fine standalone. But Claude showed no tools. The problem? A single trailing comma in my JSON config that Claude silently ignored.
This is everything I wish the docs had told me upfront.
New to MCP? Start with Introduction to MCP to understand what it is and how it works.

What This Guide Covers
You've built an MCP server (or grabbed one from GitHub). Now you need Claude Desktop to actually use it. This involves:
- Finding the right config file (it's in different places on Mac/Windows/Linux)
- Writing valid JSON config (one syntax error breaks everything silently)
- Restarting Claude Desktop the right way (closing the window isn't enough)
- Debugging when tools don't appear (they won't, the first time)
- Testing tool calls and reading logs
This assumes you have a working MCP server. If you don't, start with Building Your First MCP Server.
Quick Option: Use .mcpb Files Instead
Before diving into manual config, there's an easier way: .mcpb files are pre-packaged MCP servers that install with a double-click.
Download a .mcpb file from MCPBundles, double-click it, and Claude Desktop automatically configures everything. This is the fastest way to add MCP tools to Claude.
The rest of this guide covers the manual configuration approach - useful when you're building custom servers, need fine-grained control, or want to understand how it works under the hood.
What is a .mcpb file? | Download pre-built bundles
Installing MCP Servers via .mcpb Files
The easiest way to add MCP servers to Claude Desktop is using .mcpb files - Anthropic's packaging format for MCP servers.
What is a .mcpb file?
Think of it like a .dmg file on Mac or .exe on Windows - one file that contains everything needed to run an MCP server. Created by Anthropic as the standard packaging format.
How to install .mcpb files on Claude Desktop
- Get your MCPBundles API key (if using MCPBundles) from Dashboard Settings
- Download a
.mcpbfile from MCPBundles or another source - Double-click the file
- Claude Desktop opens automatically and prompts you to install
- Enter your API key when prompted (for MCPBundles files)
- Click Install and wait 5-10 seconds
- Tools are immediately available in your next conversation
If double-clicking doesn't work:
- macOS: Open Claude Desktop → Settings → MCP → Add Server → Browse → Select .mcpb file
- Windows: Same process, look for MCP settings in Claude Desktop
When to use .mcpb vs manual config
Use .mcpb files when:
- You want the simplest installation (one-click)
- You're using pre-built servers from marketplaces
- You don't need to customize server parameters
- You want automatic updates
Use manual config (below) when:
- You're building custom MCP servers
- You need to pass specific environment variables
- You want fine-grained control over execution
- You're working with local development servers
For most users, .mcpb files are the way to go. The manual config approach below is for developers and power users.
Want to understand .mcpb files better? Read What is a .mcpb file?
Claude Desktop MCP Config File Location
Claude Desktop stores MCP server configuration in a JSON file. The location varies by operating system.
Find Your Config File
Claude Desktop stores MCP server configuration in a JSON file. The location depends on your OS:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
Windows:
%APPDATA%\Claude\claude_desktop_config.json
Linux:
~/.config/Claude/claude_desktop_config.json
If the file doesn't exist, create it with this starter:
{
"mcpServers": {}
}
Pro tip: Open this file in VS Code or another editor with JSON validation. Claude Desktop doesn't show config errors, so you'll waste time chasing phantom issues if your JSON is malformed.
Claude Desktop MCP Server Examples
Here are working examples for different types of MCP servers:
Here's what a working config looks like:
{
"mcpServers": {
"my-notes": {
"command": "python",
"args": ["/Users/tony/projects/notes-mcp/server.py"],
"env": {
"LOG_LEVEL": "info"
}
}
}
}
Breaking this down:
"my-notes": A label for your server. Use lowercase with hyphens. This shows up in Claude's UI."command": The executable—python,node,dotnet, etc."args": Array of arguments. Use absolute paths, not relative ones."env": Optional environment variables your server needs.
Common mistakes I made:
Trailing commas:
{
"mcpServers": {
"my-notes": {
"command": "python",
"args": ["/path/to/server.py"],
} // ← This comma breaks everything
}
}
Relative paths:
"args": ["./server.py"] // ✗ Breaks - Claude doesn't know where "./" is
"args": ["/Users/tony/projects/server.py"] // ✓ Works
Wrong quotes:
"command": "python" // ✗ Smart quotes from copying docs
"command": "python" // ✓ Regular double quotes
Multiple servers:
{
"mcpServers": {
"notes": {
"command": "python",
"args": ["/path/to/notes-server.py"]
},
"tasks": {
"command": "node",
"args": ["/path/to/tasks-server/dist/index.js"]
}
}
}
Notice the comma between servers but not after the last one.
Restart Claude Desktop (Really Restart It)
Save your config, then restart Claude Desktop. Not close-the-window restart—actually quit the application.
macOS: Cmd+Q or Claude menu → Quit Claude
Windows: Right-click the taskbar icon → Quit (don't just X the window)
Linux: Use your window manager's quit command
Claude caches MCP connections on startup. If you just close the window, your changes won't load.
Test Discovery
Open Claude Desktop and start a new conversation. Ask:
"What MCP tools do you have available?"
Claude should list your tools with descriptions. If you see your tools, success! Skip to the next section.
If you don't see tools:
-
Check Claude Desktop logs
Settings → Advanced → View Logs
Look for MCP connection errors or your server name -
Test your server independently
Run the command from your config manually:python /path/to/server.pyYou should see startup logs. If it crashes, fix that first.
-
Verify the config file saved
Open it again and make sure your changes are there (easy to edit the wrong file) -
Check for JSON syntax errors
Usejqor an online JSON validator:cat ~/Library/Application\ Support/Claude/claude_desktop_config.json | jq . -
Look for process launch errors
On macOS, check Console.app for errors from Claude Desktop
Make Your First Tool Call
Once tools appear, test them. Start simple:
"Search my notes for MCP"
Watch what happens:
- Claude decides to use your
search_notestool - Claude shows you the tool call with parameters
- Your server executes and returns results
- Claude incorporates the results into its response
If the tool call fails:
- Check your server logs (they should be going to stderr)
- Look at the parameters Claude sent—does your schema match?
- Test the exact same parameters by running your server directly
Common Tool Call Problems
Claude invents fields that don't exist:
Your JSON Schema isn't strict enough. Add "required" arrays and enums:
@mcp.tool(description="Search notes")
async def search_notes(
query: Annotated[str, Field(description="Search term")],
limit: Annotated[int, Field(description="Max results", ge=1, le=50)] = 10,
sort: Annotated[
Literal["relevance", "date"],
Field(description="Sort order")
] = "relevance"
) -> dict:
...
Now Claude can't invent a sort="best" value.
Tool returns too much data:
Claude gets overwhelmed by large JSON responses. Return IDs and summaries, not full objects:
# ✗ Bad - too much data
return {"results": [full_note_object for note in results]}
# ✓ Good - just IDs
return {
"count": len(results),
"note_ids": [note.id for note in results]
}
Let Claude call another tool like get_note_by_id if it needs details.
Claude never uses your tool:
Your description isn't clear enough. Compare these:
# ✗ Vague
description="Search notes"
# ✓ Specific
description="Search through your personal notes by keyword or phrase. Use this when the user asks about their notes, ideas, or past entries."
The second one tells Claude exactly when to use it.
Learn more: Writing Great Tool Schemas for MCP
Environment Variables and Secrets
Don't hardcode API keys in your server. Use environment variables:
{
"mcpServers": {
"github": {
"command": "python",
"args": ["/path/to/github-mcp/server.py"],
"env": {
"GITHUB_TOKEN": "ghp_your_token_here",
"LOG_LEVEL": "debug"
}
}
}
}
Your server reads them:
import os
GITHUB_TOKEN = os.environ.get("GITHUB_TOKEN")
if not GITHUB_TOKEN:
raise ValueError("GITHUB_TOKEN environment variable required")
Better: Store tokens in a .env file and reference them. But for local development, putting them directly in the config works.
Debugging Tips That Actually Help
Add verbose logging:
import logging
logging.basicConfig(level=logging.DEBUG, handlers=[logging.StreamHandler()])
logger = logging.getLogger(__name__)
@mcp.tool(description="Search notes")
async def search_notes(query: str) -> dict:
logger.info(f"Received search query: {query}")
results = do_search(query)
logger.info(f"Returning {len(results)} results")
return {"results": results}
Watch your server logs while testing:
Run your server in a terminal window while using Claude Desktop. You'll see every tool call in real time.
Test tools manually first:
Before blaming Claude, call your tools directly:
import asyncio
result = asyncio.run(search_notes("MCP"))
print(result)
If this doesn't work, your tool has bugs independent of Claude.
Use correlation IDs:
Generate a unique ID for each tool call:
import uuid
@mcp.tool(description="Search notes")
async def search_notes(query: str) -> dict:
request_id = str(uuid.uuid4())
logger.info(f"[{request_id}] Search query: {query}")
# ... your code ...
logger.info(f"[{request_id}] Completed in {elapsed}s")
return results
Now you can trace specific calls through your logs.
Performance issues? Read MCP Performance: What Slow Tools Cost You
Why This Setup Works
Claude Desktop launches your server as a subprocess and communicates over stdin/stdout using JSON-RPC. This means:
- Your server must be non-interactive (no
input()prompts) - Logs must go to stderr, not stdout
- The process must stay running and responsive
- Config changes require a full restart
Once you understand this model, debugging gets much easier. Most issues are:
- Invalid JSON config
- Wrong paths
- Server crashes on startup
- Print statements breaking stdout
Fix these, and everything works.
Frequently Asked Questions
Where is the Claude Desktop MCP config file located?
The config file location depends on your operating system:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
If the file doesn't exist, create it with {"mcpServers": {}} as the starting content.
What's easier: .mcpb files or manual config?
.mcpb files are easier - just download and double-click. Manual config gives you more control but requires editing JSON files. Most users should start with .mcpb files.
For MCPBundles servers, download the .mcpb file from your dashboard and double-click to install.
How do I install a .mcpb file in Claude Desktop?
- Download the .mcpb file
- Double-click it
- Claude Desktop opens and prompts to install
- Enter your API key if required (for MCPBundles files)
- Click Install
Tools are available immediately in your next conversation.
Can I use both .mcpb files and manual config?
Yes! You can install some servers via .mcpb files and configure others manually. They work together - Claude Desktop combines all sources.
Why isn't my MCP server showing in Claude Desktop?
Common reasons:
For manual config:
- Trailing comma in JSON config
- Relative paths instead of absolute paths
- Not fully restarting Claude Desktop (use Cmd+Q on Mac, not just close)
- Server crashes on startup
For .mcpb install:
- Server crashed on startup
- Missing required credentials or API key
- Network connection issues (for cloud-connected servers)
See the troubleshooting section above for detailed fixes.
How do I add environment variables to my MCP server?
Use the "env" key in your config:
{
"mcpServers": {
"my-server": {
"command": "python",
"args": ["/path/to/server.py"],
"env": {
"API_KEY": "your-key-here",
"LOG_LEVEL": "debug"
}
}
}
}
Your server can read these using os.environ.get("API_KEY") in Python or process.env.API_KEY in Node.js.
Key Takeaways
- Use absolute paths everywhere in your config—relative paths don't work
- Watch for trailing commas in JSON—they break everything silently
- Actually quit Claude Desktop (Cmd+Q), don't just close the window
- Test your server standalone first before blaming the integration
- Add verbose logging to stderr so you can see what's happening
- Start with one server and get it working before adding more
- JSON Schema descriptions matter—the better they are, the more accurately Claude uses your tools
Resources
- What is a .mcpb file? – Understanding Anthropic's packaging format
- Download .mcpb bundles – Pre-built MCP servers ready to install
- Anthropic MCP Docs – Official Claude Desktop MCP setup
- FastMCP GitHub – Best Python MCP library
- MCP Specification – Full protocol details
- Building Your First MCP Server – Start here if you don't have a server yet
Still stuck? Drop a question—we're all figuring this out together.