You install an MCP server, restart Claude Desktop, and… nothing. No hammer icon. No error. No log line. The config looks fine. The server runs by hand. This silent failure is the single most common Anthropic MCP install experience, and it usually isn’t your fault – it’s a documented gap between what the docs say and how the app actually behaves on Windows.
This guide skips the conceptual tour and walks through deploying MCP servers the way you should be doing it in 2026: bundle-first (.mcpb), JSON-config as backup, with the specific traps that eat hours called out in the order you’ll hit them. MCP launched in November 2024 and turned one year old on November 25, 2025 with a major spec release. The install story has changed twice in that time. Most tutorials haven’t caught up.
What you’re actually installing
An MCP server is a small program that runs locally as a subprocess of Claude Desktop. Claude launches it on startup and talks to it over stdio using JSON-RPC. That’s the whole architecture. Anything more conceptual than that doesn’t help you deploy.
The latest stable spec is 2025-11-25, with a release candidate for 2026-07-28 already published. Tasks are the headline addition: the 2025-11-25 spec ships experimental support for tracking durable requests via polling and deferred result retrieval (SEP-1686). Why does that matter right now? Pre-2025-11-25, every tool call blocked synchronously – your server had to return a result before Claude could do anything else. If your server might run for minutes (a deep research pass, a long shell command), check whether its SDK has shipped Tasks support yet. Most haven’t.
System requirements
| Component | Requirement | Notes |
|---|---|---|
| OS | macOS 11+, Windows 10/11, Linux (preview) | Linux config path differs |
| Node.js | Not required for .mcpb | Claude Desktop includes a built-in Node.js runtime – Node-based bundled servers install with zero extra software |
| Python | 3.10+ if your server uses Python | Not bundled – install separately |
| Claude Desktop | Latest from claude.ai/download | Older builds lack the Extensions panel |
That bundled-Node detail trips people up constantly. Node MCP servers install cleanly. Python ones need a Python interpreter on your PATH. Mix them and you’ll spend time debugging why one server loads and the other silently doesn’t.
The fast path: install via .mcpb (recommended)
If you’re not writing the server yourself, don’t edit JSON. Use a bundle. The .mcpb name replaced an earlier .dxt extension in late 2025 – both work in Claude Desktop, so older .dxt files in documentation install the same way.
- Download the
.mcpbfile from the server author’s GitHub releases or the official Extensions directory. - Open Claude Desktop. Menu (☰) → Settings → Extensions.
- Drag the
.mcpbfile onto the Extensions page, or click Advanced settings → Install Extension… and pick the file. - Review permissions in the install dialog. Configure any required settings (API keys, paths) in the UI.
- Confirm. The server appears as enabled. No restart usually needed.
One thing to check when installing a third-party bundle: manifest fields marked "sensitive": true get encrypted via OS secure storage – Keychain on macOS, Credential Manager on Windows. If the bundle asks for an API key in a plain text field rather than a masked input, the author skipped the sensitive flag. File an issue before pasting your key.
The manual path: claude_desktop_config.json
For custom servers, private servers, or anything not yet bundled, you’ll edit JSON directly. Open Settings → Developer → Edit Config in Claude Desktop. On disk, the file lives at:
# macOS
~/Library/Application Support/Claude/claude_desktop_config.json
# Windows (per the docs - but read the next section)
%APPDATA%Claudeclaude_desktop_config.json
# Linux
~/.config/Claude/claude_desktop_config.json
A minimal working config that gives Claude filesystem access:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/yourname/Documents"
]
}
}
}
Save. Fully quit Claude Desktop (Cmd+Q on macOS, tray → Quit on Windows – closing the window isn’t enough). Reopen. At the bottom of a new chat window you should see a hammer icon with a number: that’s how many tools registered. Click it to see the list. No hammer means the server failed silently. Check the logs next to your config file – they’re named per-server and contain stderr output from startup.
The Windows MSIX trap nobody warns you about
This one burned the community for a while before it landed in GitHub issue #26073. Install Claude Desktop on Windows from the official installer and you’re running an MSIX-packaged app. The Edit Config button opens %APPDATA%Claudeclaude_desktop_config.json. The app reads from somewhere else entirely:
%LOCALAPPDATA%PackagesClaude_pzs8sxrjxfjjcLocalCacheRoamingClaudeclaude_desktop_config.json
Edit that file. Not the one Edit Config shows you. Yes, this is absurd. MSIX apps run inside a lightweight container with a virtualized filesystem – when Claude accesses %APPDATA%Claude, Windows silently redirects to the virtualized path. The Edit Config button uses an Electron API that bypasses the redirect. Result: you save to one file, the app reads another, nothing breaks visibly. Unfixed as of early 2026.
The catch: on Windows, also wrap every npx command with cmd /c. So "command": "npx" becomes "command": "cmd" with "args": ["/c", "npx", "-y", "@some/server"]. Without this, Windows can’t execute npx from the spawned subprocess – you get “Connection closed” and nothing else.
Common errors with their actual fix
These are the failure modes you’ll actually meet, in rough frequency order:
- “ERROR: You must supply a command” in the log → your
argsarray is missing the package name. The-yflag alone isn’t enough; you need["-y", "@modelcontextprotocol/server-x"]. - Server transport closed unexpectedly → your server is writing logs to stdout. Per the MCP spec, stdout is reserved for JSON-RPC protocol traffic – any stray print call corrupts the stream and drops the connection. Logs go to stderr only.
- Relative paths fail silently → Claude Desktop’s working directory isn’t your terminal’s.
"./server.py"won’t resolve. Use absolute paths inargs, always. - All servers disabled after a JSON edit → trailing comma somewhere. Validate with
jqor any JSON linter before restarting. No error is shown when this happens.
That last one is worth sitting with for a second. A single trailing comma silently disables every server in your config. You won’t see an error in the UI, won’t see a log entry, won’t see anything – just the same empty state as a fresh install. Run your JSON through a linter before every restart, not just when something breaks.
Verify it actually works
Quit fully. Relaunch. Open a new chat. Look at the input area:
- Hammer icon with a number → server connected, tools registered. Click it to list them.
- No hammer icon → server failed silently. Check logs next to the config file.
- Hammer icon, but “0 tools” → server connected but registered nothing. Usually a code bug in the server, not your config.
On macOS, log files live next to the config in ~/Library/Application Support/Claude/ and are named per-server. Tail them while restarting Claude to catch startup errors in real time.
Upgrading and uninstalling
For .mcpb bundles: open Settings → Extensions, find the server, click Uninstall – or drag a newer .mcpb on top to replace it.
For manual JSON servers, “upgrade” usually means bumping a version in the npx args (or letting -y grab latest on every launch) and restarting Claude. To remove cleanly: delete the entry from mcpServers, save, restart. Cached npm packages under your user cache directory are harmless to leave.
One migration consequence worth knowing: the June 2025 spec update classified MCP servers as OAuth Resource Servers and removed JSON-RPC batching. Servers still using batching from the 2025-03-26 era won’t talk to current clients.
Bonus: packaging your own server as .mcpb
Built a server worth sharing? Ship a bundle. The CLI:
npm install -g @anthropic-ai/mcpb
cd your-mcp-server/
mcpb init # generates manifest.json interactively
mcpb pack # produces your-server.mcpb
Anyone can drop the output onto their Extensions panel. Source and spec at github.com/modelcontextprotocol/mcpb.
FAQ
Do I need to use Claude Desktop, or can I use MCP with other apps?
No. Cursor, VS Code with Claude Code, and Zed all speak MCP – though config keys and paths differ between them. Claude Desktop just happens to have the largest third-party server platform because Anthropic ships it directly.
Why does my server work standalone but not in Claude Desktop?
Start here: run the exact command from your config in a fresh terminal session – not your dev shell with custom PATH entries and env vars loaded. If the server errors there, that’s your fix. If it runs fine standalone, the problem is almost always stdout pollution (the server prints something to stdout, the JSON-RPC stream breaks, Claude drops the connection silently). Add a log statement at startup to stderr and tail the log file while relaunching Claude. You’ll see the crash immediately.
Is the new async Tasks feature production-ready?
No – it’s marked experimental in the 2025-11-25 spec, and most SDKs haven’t shipped it yet. Design tools to return within seconds for anything you ship today. The 2026-07-28 RC is the milestone to watch for stabilization.
Next step: open Settings → Extensions in Claude Desktop right now, install one official bundle (Filesystem is the safest first pick), and ask Claude to list the files in a directory you trust. Hammer icon shows tools, Claude reads the files – your MCP install is real.