---
title: 'MCP Server Not Showing Up in Claude Desktop: Fixes (2026)'
description: MCP server not showing up in Claude Desktop? Check the Connectors menu, the config's JSON, a full quit, mcp.log, and the file the app reads — in that order.
url: https://nerdleveltech.com/mcp-server-not-showing-up-in-claude-desktop
language: en
date: '2026-08-20'
category: ai-ml
tags:
  - mcp
  - claude desktop
  - model context protocol
  - claude_desktop_config.json
  - desktop extensions
  - mcp inspector
  - troubleshooting
markdown_url: https://nerdleveltech.com/mcp-server-not-showing-up-in-claude-desktop.md
attribution: 'Source: NerdLevelTech — https://nerdleveltech.com/mcp-server-not-showing-up-in-claude-desktop'
terms: https://nerdleveltech.com/llms.txt
---

# MCP Server Not Showing Up in Claude Desktop: Fixes (2026)

When an MCP server is not showing up in Claude Desktop, work in this order: check the Connectors menu and Developer settings, validate the config JSON, fully quit and reopen the app, read `mcp.log`, then confirm you edited the file the app actually reads.[^local][^debug]

## TL;DR

Claude Desktop starts the servers listed under `mcpServers` in `claude_desktop_config.json` when you launch it.[^local] The chain from "I edited a file" to "a tool appears in a conversation" has several links, and the ones that cost the most time are the ones that fail quietly: a config file the app never read, which on one reported Windows configuration produces no error, no logs and no indication in Developer settings[^msix]; an app that was closed rather than quit, and a managed-device policy that is set outside the app entirely.[^enterprise] That quietness is what makes guessing expensive and reading a log file cheap.

The sections below tackle an MCP server not showing up in Claude Desktop in an order that puts the checks costing you nothing — looking in a menu, running one command — before the ones that require you to change something. That ordering is about cost, not likelihood; your particular cause may well be near the bottom, but you will reach it faster having ruled the free ones out first.

One scoping note. Claude Desktop can gain tools through more than one mechanism, and they fail differently. If you are not certain which you set up, start with ["Which mechanism did you actually use?"](#which-mechanism-did-you-actually-use).

## What you'll learn

- Which MCP mechanism you actually configured, and why that changes every step that follows
- How to check whether the server is already connected before you change anything
- How to validate the config file's JSON, and what Claude Desktop does when it will not parse
- Why closing the Claude Desktop window is not a restart
- How to read `mcp.log` and `mcp-server-NAME.log`, and what each one rules in or out
- Where `claude_desktop_config.json` lives — and the reported Windows case where "Edit Config" opens a file the app does not read
- Why a server that runs fine in your terminal can fail under Claude Desktop, and how to fix the environment
- How a stray line of logging can start your server and still break the protocol
- How to prove the server itself works, using MCP Inspector
- What to do when a desktop extension installs but its tools never appear
- The managed-device policy key that disables local MCP servers outright, and how to read its current value yourself
- Why a connector can work on claude.ai and not in Claude Desktop, and the reverse
- Which plan and organisation limits are documented, and which mechanism each one applies to

## Which mechanism did you actually use?

Several different things put tools in Claude Desktop, and the troubleshooting for each is different. Identify yours first.

| What you did | Mechanism | Where it lives | Documented availability |
|---|---|---|---|
| Edited a JSON file by hand | Local MCP server | `claude_desktop_config.json` | Claude Desktop; "aren't available in Cowork or claude.ai"[^connectors] |
| Clicked Install in Settings → Extensions | Desktop extension (`.mcpb`) | Claude Desktop's extension registry | "only available in Claude Desktop and Claude Code—not on web or mobile"[^when] |
| Pasted an `https://` URL into Connectors | Remote custom connector | Your Claude account | All Claude surfaces[^when] |
| Installed a plugin | Either or both | Depends what the plugin bundles | Follows whichever it bundles[^when] |

That last row catches people out. Anthropic's guidance is explicit that "a plugin can bundle either remote or local MCP servers (or both)," and that a plugin referencing a remote MCP "makes it available everywhere," while one referencing a local MCP "works in Desktop and Claude Code."[^when] So if you installed a plugin and are debugging where its tools went, first work out which kind of server it brought with it — then follow that mechanism's section below.

The distinction matters because the availability rules are not symmetric. Desktop extensions and local config servers are machine-local and do not appear on the web client; remote connectors are reached from Anthropic's infrastructure and appear everywhere.[^when][^connectors]

## How do I check whether an MCP server connected in Claude Desktop?

Do this before you change anything, because it costs nothing and it can end the search on the spot.

There are two places to look, and Anthropic's help centre names both: "Click the '+' button on bottom the chat box within Claude Desktop, then select 'Connectors.' … Alternatively, you can visit Developer settings (under Desktop app) to see connection status and look at the logs for any MCP servers."[^extensions] MCP's own pages describe the same first route in more detail — click the "Add files, connectors, and more" indicator at the bottom-left of the conversation input, hover **Connectors**, then **Manage connectors**, and select your server to see the tools it exposes.[^local][^debug]

Two things worth knowing before you go looking:

- **The menu is called Connectors regardless of mechanism.** Anthropic's own instructions send you to it to check local MCP servers,[^extensions] so the name tells you nothing about which mechanism you configured — do not conclude your local server is in the wrong place because the menu says "Connectors."
- **Check Developer settings too, not just the menu.** Anthropic describes the Connectors route as showing "connected MCP servers and their tools", and Developer settings as showing connection status and logs.[^extensions] The second is the one to trust when something is wrong, because a status field is more specific than a list. If your server is listed but unusable, jump to [per-tool disabling](#why-does-my-connector-work-on-claudeai-but-not-in-claude-desktop).

A note on the icon, because it sends a lot of people down the wrong path. Many third-party guides tell you to look for a hammer icon at the bottom-right of the input box. MCP's documentation still uses that phrasing as a *symptom label* — one troubleshooting accordion is titled "Server not showing up in Claude / hammer icon missing" — but every actual *instruction* on both current MCP pages points at the plus icon and the Connectors menu instead.[^local][^debug] If you are hunting for a hammer and not finding one, that on its own tells you nothing about whether your server connected.

## Does my config file actually parse?

This is the second free check, and it is an easy one to skip because the file looks fine. Claude Desktop's config is a single JSON document; if it is not valid JSON, there is nothing for the app to read, and the quickstart's own troubleshooting list puts "Check your `claude_desktop_config.json` file syntax" second only to restarting.[^local]

Validate it with a parser rather than by eye. These forms print `OK` or an error position and deliberately do **not** echo the file, because your config may contain API keys in an `env` block and this output tends to end up pasted into forum threads:

```bash
# macOS
python3 -c 'import json,sys; json.load(open(sys.argv[1])); print("OK")' \
  ~/Library/Application\ Support/Claude/claude_desktop_config.json
```

```powershell
# Windows PowerShell
$null = Get-Content "$env:APPDATA\Claude\claude_desktop_config.json" -Raw | ConvertFrom-Json; "OK"
```

On a clean macOS install `python3` may not be present — it is a stub that offers to install the command line developer tools. If you would rather not, any parser will do; the point is that a machine reads the file, not you.

Not from the docs, but from experience, the usual offenders are: a trailing comma after the last entry; a `//` comment, which JSON has no syntax for; a missing closing brace; curly quotation marks pasted in from a word processor or a web page; a UTF-8 byte-order mark, which Notepad and PowerShell 5.1 both like to add and which some parsers reject while `ConvertFrom-Json` quietly accepts; and — on Windows — single backslashes in a path. In JSON, `\` starts an escape sequence, so a backslash-separated Windows path has to double each one: `C:\\Users\\username\\Desktop`. Forward slashes are also valid JSON and work on Windows, so `C:/Users/username/Desktop` sidesteps the problem entirely.

One trap a parser will not catch: two `mcpServers` keys in the same document is *valid* JSON, and every parser I tested silently keeps only the last one. If you merged a snippet in rather than editing the existing key, half your servers disappear with no error anywhere. `grep -c '"mcpServers"' <file>` should print `1`.

A clean parse here proves the file you tested is valid; on Windows it does not yet prove it is the file the app reads — see [the Windows two-file case](#the-windows-two-file-case) below. And this check has a Windows-specific cousin worth doing at the same time: text editors that append `.txt` on save. If your file browser is hiding known extensions, `claude_desktop_config.json.txt` looks identical to the file you meant to create, and produces exactly the same symptom as having no config at all.

There is a log line worth recognising while you are here. Issue #38830 quotes a Claude Desktop `main.log` entry reading `[error] Error reading or parsing config file:` followed by a `SyntaxError` and a character position.[^msix2] It tells you the app tried to read a config and could not. It does not tell you *which* file, and it is not proof your syntax is wrong: that reporter's files parsed cleanly under `ConvertFrom-Json`, and they described the source of the error as unidentified.[^msix2] So treat the string as a prompt to check both your syntax and [the Windows two-file case](#the-windows-two-file-case), not as a verdict on either.

## Do I have to fully quit Claude Desktop for the config to take effect?

Yes, and closing the window does not count. The quickstart's instruction after saving the config is to "completely quit Claude Desktop and restart it," because "the application needs to restart to load the new configuration and start the MCP server."[^local] MCP's debugging guide says the same for server code changes, in terms worth quoting because they name the exact mistake: "Restart the client (for Claude Desktop, fully quit and reopen; closing the window is not enough)."[^debug]

On macOS this is the difference between the red close button and quitting the application outright — the first leaves the process running, so nothing is re-read and your edit appears to have done nothing.

Issue #26073's reproduction steps mention a Developer → **Reload MCP Configuration** menu item as an alternative.[^msix] Treat it as a faster loop once things work, not as your first test: a full quit is the behaviour the documentation describes, and you want your first negative result to be trustworthy.

## How do I read Claude Desktop's MCP logs?

Claude Desktop writes MCP logs to `~/Library/Logs/Claude` on macOS and `%APPDATA%\Claude\logs` on Windows.[^local] Two kinds of file live there and they answer different questions:

- **`mcp.log`** — "general logging about MCP connections and connection failures."[^local] This is where you see whether Claude Desktop attempted your server at all.
- **`mcp-server-NAME.log`** — written `mcp-server-SERVERNAME.log` in the docs, where the placeholder is the key you gave the server in your config. It holds that one server's stderr. The docs warn that "stdio servers may use stderr for all their logging, so these files are not limited to errors," so a busy file is not automatically a bad sign.[^local]

Do this as a sequence rather than a live tail, because on a first-time failure `mcp-server-NAME.log` does not exist yet — it gets created by the restart, and a shell glob expands once, before that happens:

```bash
# macOS: quit Claude Desktop fully, reopen it, wait a few seconds, then
ls -la ~/Library/Logs/Claude/
tail -n 100 ~/Library/Logs/Claude/mcp*.log
```

On Windows, MCP's debugging page gives this form, which expands the environment variable correctly under PowerShell:[^debug]

```powershell
type "$env:AppData\Claude\logs\mcp*.log"
```

That concatenates every matching file with no filename headers and no tail limit, which is awkward when the whole point is telling `mcp.log` apart from `mcp-server-NAME.log`. This does the same job as the macOS pair above — list first, then read each file labelled:

```powershell
Get-ChildItem "$env:APPDATA\Claude\logs"
Get-ChildItem "$env:APPDATA\Claude\logs" -Filter mcp*.log | ForEach-Object {
  "`n==> $($_.Name) <=="; Get-Content $_.FullName -Tail 100
}
```

Read a blank result carefully on either platform: a glob that matches nothing prints nothing, which looks identical to files that exist and are empty. The listing step is what tells those apart.

The logs capture connection events, configuration issues, runtime errors, and message exchanges.[^debug] What you are reading for is which layer failed:

| What you see | What it points at | Go to |
|---|---|---|
| No `mcp-server-NAME.log`, nothing in `mcp.log` about your server | Consistent with Claude Desktop never having tried to start it — config not read, config not parsed, or local MCP disabled by policy | [config file](#where-is-claude_desktop_configjson-and-am-i-editing-the-one-the-app-reads), [JSON](#does-my-config-file-actually-parse), [policy](#can-an-admin-policy-disable-local-mcp-servers-on-my-machine) |
| A parse error naming a character position | Invalid JSON | [JSON](#does-my-config-file-actually-parse) |
| `mcp-server-NAME.log` exists and shows the process dying immediately | The command could not be found or run | [environment](#why-does-my-mcp-server-work-in-the-terminal-but-not-in-claude-desktop) |
| Server starts, logs normally, exposes nothing | Protocol-level problem — relevant if you wrote the server | [stdout](#could-my-server-be-starting-and-then-breaking-the-protocol) |

If you are on Windows and the log folder itself does not exist at the documented path, that matches what issue #26073 reports for the packaging problem in the next section — though a Claude Desktop that has never started an MCP server is another explanation, so treat it as a pointer rather than a diagnosis.[^msix]

## Where is claude_desktop_config.json, and am I editing the one the app reads?

The documented locations are `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS and `%APPDATA%\Claude\claude_desktop_config.json` on Windows.[^local] The in-app route on macOS starts from the Claude menu in your system menu bar — not the settings inside the Claude window — then Settings…, then the **Developer** tab, then **Edit Config**, which opens the file and creates it first if it does not exist.[^local]

The config schema MCP documents for this file is narrow: an `mcpServers` object, one key per server, each holding a `command` plus optional `args` and `env`.[^local][^debug] Neither MCP page cited here shows a `type` key in a Claude Desktop example. That is an observation about the documentation, not a rule — if you copied a `"type": "stdio"` line from a guide it may still be harmless, but it is not something these docs ask for, so do not assume its presence or absence is what fixed or broke things.

The quickstart tells you to "replace the contents of the configuration file" with a complete document.[^local] That is fine on a fresh install, but if your file already holds other servers or a `preferences` block, you want to merge instead. Here is the `mcpServers` key on its own, to nest inside the braces you already have:

```json
"mcpServers": {
  "filesystem": {
    "command": "npx",
    "args": [
      "-y",
      "@modelcontextprotocol/server-filesystem",
      "C:\\Users\\YOUR-USERNAME\\Desktop"
    ]
  }
}
```

And here is the same thing as a complete file, for the empty-config case — note the outer braces, without which nothing above parses:

```json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "C:\\Users\\YOUR-USERNAME\\Desktop"
      ]
    }
  }
}
```

### The Windows two-file case

On Windows there is a publicly reported exception to everything above, and it is worth ten seconds to rule out. First, check whether it can apply to you at all:

```powershell
Get-AppxPackage *Claude* | Select-Object Name, PackageFamilyName
Test-Path "$env:LOCALAPPDATA\Packages\Claude_pzs8sxrjxfjjc"
```

If `Get-AppxPackage` returns nothing at all, you are not on an MSIX build and the rest of this section does not apply. Do not lean on the `Test-Path` line alone: issue #26073 notes that "a second package also exists at `Anthropic.ClaudeDesktop_h6f0761` which may be related to the confusion," so a `False` against one package name does not by itself rule the case out.[^msix]

If either command shows an MSIX package, you may have the build described in issue #26073, filed in February 2026. The reporter states that "Edit Config" opens `C:\Users\<username>\AppData\Roaming\Claude\claude_desktop_config.json` while the app reads `C:\Users\<username>\AppData\Local\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\claude_desktop_config.json` — two separate files that are never synchronised.[^msix] The attributed mechanism is MSIX filesystem virtualisation: the app's own reads of `%APPDATA%` are redirected into the package's `LocalCache`, while the shell call that opens your editor resolves the real, non-virtualised path.[^msix]

The failure mode is what makes it hard to spot. Per that report: no error in the app, no logs folder at the documented `%APPDATA%\Claude\logs\` location, and nothing in Developer settings indicating the config was not loaded.[^msix]

Two caveats before you act on it. First, this is a user-filed bug report in Anthropic's public `claude-code` tracker rather than vendor documentation. It carries both a `bug` and an `invalid` label, but note what that second one means on this repository — its description reads "Issue doesn't seem to be related to Claude Code," which is a routing judgement about the tracker (this is Claude Desktop, a different product), not a finding that the report is wrong.[^msix] Second — and this is why it is a hypothesis rather than a diagnosis — it does not explain every case. A later report, #38830, describes an MSIX install on version 1.1.8629.0 where the reporter placed `mcpServers` in *both* files, states that "Both files have been kept in sync and both contain valid JSON with mcpServers," and still saw "No servers added" in Settings → Developer with no `mcp-server-*.log` files created at all. That report's own log excerpt shows a JSON `SyntaxError` against files that "validate successfully with `ConvertFrom-Json` in PowerShell — the source of this parse error is unidentified."[^msix2] So syncing the two files is worth doing, but do not assume it is sufficient.

If a second config file does exist, merge your `mcpServers` key into it rather than replacing it — the report notes the virtualised file already carries a `preferences` block.[^msix] Then stop using **Edit Config** on that machine and open the `LocalCache` path directly from then on, or your next edit lands back in the file the app ignores.

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

Because the two are not the same environment. MCP's debugging guide states that servers launched over stdio — the local kind, which talk to Claude Desktop over standard input and output — "inherit only a limited subset of environment variables automatically (the exact set is platform-dependent)."[^debug] Your shell has a `PATH` assembled by your login profile, your version manager, and your package manager. The process Claude Desktop spawns does not necessarily have any of that, so a bare `npx`, `uvx`, `python`, or `docker` in `command` can resolve in your terminal and fail under the app.[^debug]

Two documented fixes, and one detail that decides whether the first actually works.

1. **Use absolute paths.** The guide's advice under path issues is "Try using an absolute path for `command`", and more broadly, "Always use absolute paths in your configuration and `.env` files to ensure reliable operation."[^debug]
2. **Declare what the server needs via `env`.** The `env` key exists to "override the default variables or provide your own."[^debug]

The detail, which is not in the docs but follows from them: if you use a Node version manager, pointing `command` at the manager's `npx` may not be enough on its own, because those launcher scripts typically resolve `node` from `PATH` at run time — and `PATH` is the thing that is missing. Point `command` at the `node` binary itself, pass your server's script as the first argument, and add the directory containing `node` to `PATH` in the `env` block. Run `which node` on macOS, or `where.exe node` on Windows — plain `where` in PowerShell is an alias for `Where-Object` and will silently print nothing, which looks exactly like "Node is not installed". If your version manager uses shims (asdf, Volta), `which` hands you the shim rather than the binary; `node -e 'console.log(process.execPath)'` always prints the real path. Either way, do not guess at `/usr/local/bin`.

Again the `mcpServers` key alone, to merge into your existing braces — replace every `YOUR-USERNAME` and version number with the real values from your own machine:

```json
"mcpServers": {
  "myserver": {
    "command": "/Users/YOUR-USERNAME/.nvm/versions/node/v22.19.0/bin/node",
    "args": ["/Users/YOUR-USERNAME/servers/myserver/dist/index.js"],
    "env": {
      "PATH": "/Users/YOUR-USERNAME/.nvm/versions/node/v22.19.0/bin:/usr/bin:/bin",
      "MYAPP_API_KEY": "some_key"
    }
  }
}
```

The working directory is the second trap in this family. The guide notes it "may be undefined (like `/` on macOS)" because the client could have been started from anywhere.[^debug] Any relative path in `args` is therefore resolved against a directory you did not choose. The same goes for `~`, though this one is not in the docs: the tilde is expanded by your shell, and JSON has no such rule, so a literal `"~/Desktop"` inside the config reaches your server as a directory name that does not exist. Write `/Users/you/Desktop`. The quickstart says the same thing from the other side — make sure the paths in `claude_desktop_config.json` "are valid and that they are absolute and not relative."[^local]

Windows has one more documented variant. If your server's log shows an error referring to `${APPDATA}` inside a path, add the expanded value of `%APPDATA%` to that server's `env` key. The docs also warn that `npx` "may continue to fail if you have not installed npm globally" — you can confirm a global install by checking whether `%APPDATA%\npm` exists, and create one with `npm install -g npm`.[^local]

## Could my server be starting and then breaking the protocol?

This one produces a server that launches, logs normally, and still exposes nothing — so it is worth knowing about even though it only applies if you wrote the server yourself.

Local MCP servers speak the protocol over stdout. MCP's guide is unambiguous: local servers "should not log messages to stdout (standard out), as this will interfere with protocol operation."[^debug] A `print()` or `console.log()` anywhere in a startup path is enough to violate that. Send logs to stderr instead, which the host application — Claude Desktop, here — captures automatically for stdio servers.[^debug] (The rule flips for the Streamable HTTP transport, where "stderr is not captured by the client" and the docs point you at your own server-side log aggregation or OpenTelemetry, plus ordinary HTTP tooling such as curl or the browser's Network panel. Note while you are there that protocol-level logging via `notifications/message` is "deprecated as of protocol version `2026-07-28`," so do not build new servers around it.[^debug])

There is a related class of failure in capability negotiation, where the two sides do not agree on what each supports. In the `2026-07-28` protocol the docs are specific about where to look: every request must carry `io.modelcontextprotocol/protocolVersion` and `io.modelcontextprotocol/clientCapabilities` in its `_meta`, a request missing either is rejected with `-32602` ("Invalid params", also returned for many other malformed inputs), and a server that needs a capability the client never declared — elicitation, for instance — returns `MissingRequiredClientCapabilityError` (`-32021`) naming what is missing. The suggested check is to "inspect the request's `_meta` and the `server/discover` response to verify both sides declared what you expect."[^debug] Inspector's monitoring sidebar is the easiest place to watch that traffic.[^inspector] These names and codes are specific to that protocol version, so check them against the version your server targets.

## How do I test my MCP server with MCP Inspector?

Use MCP Inspector to establish whether the server is even the problem. The debugging guide lists it first among debugging tools and says plainly: "This should be your first stop."[^debug] It ships as one package, `@modelcontextprotocol/inspector`, with three clients behind a single binary — a web UI, a scriptable CLI, and a terminal UI — all sharing the same core, transports, and configuration.[^inspector] The docs give its floor as "Node 22.19.0 or newer", so check `node -v` first; on an older runtime, fall back to running the server's command directly in a terminal, which the quickstart also suggests as a troubleshooting step.[^inspector][^local]

```bash
# Web UI, pointed at a local stdio server
npx -y @modelcontextprotocol/inspector node /abs/path/to/server/index.js

# List the tools and exit — the fastest possible sanity check
npx -y @modelcontextprotocol/inspector --cli node /abs/path/to/server/index.js --method tools/list

# A published npm server, launched the way your config launches it
npx -y @modelcontextprotocol/inspector npx -y @modelcontextprotocol/server-filesystem /Users/YOUR-USERNAME/Desktop
```

The third form is the useful one here, because it runs the same `command` and `args` your config does — provided you write out the same literal strings. Use the absolute path in both places rather than `~`, or the two invocations are not comparable for exactly the reason described in the previous section.

Now read the result as a branch, not a checklist:

- **Inspector fails too.** The fault is in the server or its dependencies. Stop editing JSON.
- **Inspector succeeds, Claude Desktop shows nothing.** The server itself is fine, so the difference is something between your config and the process Claude Desktop spawns. In rough order: the environment your shell provides and the spawned process does not — go to [absolute paths and `PATH`](#why-does-my-mcp-server-work-in-the-terminal-but-not-in-claude-desktop) and hardcode `command`, `args` and `PATH`; then whether the app read your config at all ([logs](#how-do-i-read-claude-desktops-mcp-logs), [the Windows two-file case](#the-windows-two-file-case)); then [device policy](#can-an-admin-policy-disable-local-mcp-servers-on-my-machine).

For a remote server, the docs' CLI example passes the URL positionally (their web-mode example uses `--server-url` instead):[^inspector]

```bash
npx -y @modelcontextprotocol/inspector --cli https://api.example.com/mcp --transport http --method tools/list
```

Two syntax rules that cause avoidable confusion:[^inspector]

- Mode flags (`--web`, `--cli`, `--tui`) are recognised only at the front of the command line, so a later `--cli` is forwarded to your server untouched.
- Passing two of them errors with "Specify at most one of --web, --cli, or --tui."

## My desktop extension installed, but its tools never appeared

Extensions are installed through Settings rather than by editing `claude_desktop_config.json`, and Anthropic's remedy for a misbehaving one is to "restart Claude Desktop to refresh the extension registry" — so the config-file checks above are not where to look. Anthropic's documented remedies for "extension appears installed but tools aren't available" are: restart Claude Desktop to refresh the extension registry; check the extension's configuration settings for missing required fields; and verify that any API keys or authentication credentials were entered correctly.[^extensions] A separate list for configuration problems adds the navigation — Settings → Extensions, then click the extension to review its settings — and notes that any file paths you supply need to point at directories that exist and that you can access.[^extensions]

Worth knowing while you are in there: extensions do not depend on your Node installation. Claude Desktop "includes a built-in Node.js environment, so Node.js installation isn't required" for extensions, and they support Node.js, Python, and binary MCP servers.[^extensions] In practice that means an extension can work on a machine where a hand-configured `npx` server fails for `PATH` reasons — useful to know when you are deciding which mechanism to bother debugging. Sensitive fields marked `"sensitive": true` in the manifest are encrypted using the operating system's secure storage, such as Keychain on macOS or Credential Manager on Windows.[^extensions]

If you are installing a `.mcpb` extension you built or received rather than one from the directory, the path is Settings → Extensions → "Advanced settings" → the **Extension Developer** section (a different pane from Settings → Developer) → "Install Extension…" → select the file.[^extensions] And if you built it, it stays current only if you reinstall: directory extensions update automatically by default, while for privately distributed extensions, "users will need to install updated .mcpb files manually."[^extensions]

## Can an admin policy disable local MCP servers on my machine?

Yes — and on a work laptop this deserves checking before you spend more time on JSON. Administrators on Team or Enterprise plans can control Claude Desktop through system policies, and the documented policy table includes `isLocalDevMcpEnabled`, a Boolean that defaults to `true` and is described as "Enable local MCP servers."[^enterprise] Two sibling keys govern the other mechanism: `isDesktopExtensionEnabled` ("Enable/disable extensions") and `isDesktopExtensionDirectoryEnabled` ("Enable extension directory access"), both also defaulting to `true`.[^enterprise]

Delivery differs by platform. On macOS the settings arrive by MDM configuration profile against the preferences domain `com.anthropic.claudefordesktop`, with Jamf Pro, Kandji, and Intune named as tools.[^enterprise] On Windows they arrive by Group Policy or Intune, written under `HKLM:\SOFTWARE\Policies\Claude` for machine-wide settings or the HKCU equivalent per user, with machine-level settings taking priority when both are set.[^enterprise] Anthropic also notes that enterprise policy controls at the user-machine level override the in-app extension allowlist.[^enterprise]

You can look at the documented locations yourself rather than waiting on IT. On Windows, check both scopes — Anthropic's own example writes to `HKLM:\SOFTWARE\Policies\Claude`, and the article names HKCU as the per-user equivalent:[^enterprise]

```powershell
foreach ($p in 'HKLM:\SOFTWARE\Policies\Claude','HKCU:\SOFTWARE\Policies\Claude') {
  if (Test-Path $p) {
    "$p ->"
    Get-ItemProperty $p | Select-Object isLocalDevMcpEnabled, isDesktopExtensionEnabled, isDesktopExtensionDirectoryEnabled
  } else { "$p -> key not present (no policy set at this scope)" }
}
```

Written this way rather than with `-ErrorAction SilentlyContinue`, because silently swallowing errors makes "no policy set" and "you are not allowed to read this key" look identical.

macOS is less conclusive, because MDM-delivered settings do not live in the per-user preferences that `defaults read <domain>` returns. Check the managed-preferences location as well as the user domain, and expect to need administrator rights for a full picture:

```bash
# device-scoped payload, then user-scoped, then the user's own preferences
defaults read "/Library/Managed Preferences/com.anthropic.claudefordesktop" 2>/dev/null || echo "no device-scoped payload"
defaults read "/Library/Managed Preferences/$USER/com.anthropic.claudefordesktop" 2>/dev/null || echo "no user-scoped payload"
defaults read com.anthropic.claudefordesktop 2>/dev/null || echo "no user preferences"

sudo profiles show -all                  # every installed configuration profile
```

Both scopes matter: MDM tools deliver payloads at device or user level, and checking only `/Library/Managed Preferences/` misses the second. `defaults read` on a domain that does not exist writes its complaint to stderr and exits non-zero, which is why the fallbacks above are there.

If `isLocalDevMcpEnabled` comes back as `0` or `false`, that is your answer, and the fix is not yours to make — it is a request to whoever manages the device to set the key back to `true` (or `1` on Windows). Read a null result carefully on either platform: an empty response means you did not find a policy in the place you looked, not that no policy exists. On a machine you do not administer, treat this section as a question to ask rather than a check you can close out.

## Why does my connector work on claude.ai but not in Claude Desktop?

Start by ruling out the mechanism itself, because for remote connectors this symptom should not occur. Anthropic documents that "Claude connects to your remote MCP server from Anthropic's cloud infrastructure, rather than from your local device," and that this holds "across every Claude client, including claude.ai, Claude Desktop, Cowork, and the mobile apps."[^connectors] A remote connector that works in the browser is therefore reaching the server the same way in the desktop app.

If you are genuinely seeing the difference, the variable is not the connector — it is per-conversation or per-tool state in that specific chat:

- **Per-conversation toggles.** The "+" button shows your configured connectors "with toggles allowing you to enable/disable them per conversation."[^connectors] A connector switched off for this chat is not a broken connector.
- **Per-tool disabling.** The "Search and tools" menu lets you disable individual tools you do not want Claude to invoke.[^connectors] A connector can be listed with the specific tool you are looking for turned off.
- **Where the tool call is coming from.** This one applies to local servers rather than remote connectors, but it belongs in the same family of "connected yet unused": advanced research is "not currently able to invoke tools from local MCP servers."[^connectors] If your local server appears under Connectors in an ordinary conversation but never gets used during research, that is documented behaviour rather than a fault.

There is a second asymmetry, and it runs the other way. Because remote connectors are reached from Anthropic's infrastructure, a server "hosted on a private corporate network, behind a VPN, or blocked by a firewall won't connect, even if you can reach them from your own machine" — the documented remedy being to allowlist Anthropic's published IP ranges.[^connectors] And the reverse of the section title is not a fault at all: a local server configured in `claude_desktop_config.json` runs on your machine, and Anthropic states these "aren't available in Cowork or claude.ai."[^connectors] Its absence from the web client is the design, not a bug to chase.

## Does my plan or my organisation's setup limit this?

For remote custom connectors, availability is documented directly: they are "available on Claude, Cowork, and Claude Desktop for users on Free, Pro, Max, Team, and Enterprise plans," and "Free users are limited to one custom connector."[^connectors] A separate article puts remote connectors on "web, mobile, Cowork, Desktop, and Claude Code."[^when] So on a free account, expect that documented one-connector limit rather than a fault.

On Team and Enterprise plans there is an extra gate. "Only Owners can add them to Team and Enterprise plans," after which individual members connect to the connector themselves.[^connectors] If you are a member rather than an Owner and your custom connector never shows up, adding it may simply not be an action available to you — the Owner adds it at the organisation level first, and it then appears in your list for you to connect. Anthropic also notes that connectors cannot be edited in place: to change one, remove it and add it again.[^connectors]

No comparable plan requirement is documented for local `claude_desktop_config.json` servers in any of the pages cited here. The plan limits above apply to remote custom connectors specifically, so do not infer that a free account is the reason a local server is missing.

## Frequently asked questions

**Why is my MCP server not showing up in Claude Desktop?**
Work the free checks first: look under Connectors and in Developer settings to see whether it is already connected, validate the config file's JSON, fully quit and reopen the app, read `mcp.log` to see whether a launch was even attempted, and — on Windows especially — confirm you edited the config file the app actually reads. Only then start changing the environment or the paths.[^local][^debug][^msix]

**Which MCP mechanism am I actually using?**
If you edited a JSON file by hand, it is a local server in `claude_desktop_config.json`. If you clicked Install in Settings → Extensions, it is a `.mcpb` desktop extension, "only available in Claude Desktop and Claude Code—not on web or mobile." If you pasted an `https://` URL into Connectors, it is a remote custom connector and works on every Claude surface. If you installed a plugin, it can bundle either kind.[^when][^connectors]

**Where is `claude_desktop_config.json`?**
`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows. On macOS, the Claude menu in your system menu bar — not in-window settings — then Settings… → Developer → Edit Config opens it, and creates it if it does not exist.[^local]

**How do I check my config file is valid JSON?**
Run it through a parser rather than reading it. Checking the file's syntax is the quickstart's own second troubleshooting step, and "Invalid JSON syntax" is listed among the documented configuration errors.[^local][^debug] Use a form that prints only `OK`, since the file may hold API keys. Beyond syntax, watch for two silent ones: a duplicate `mcpServers` key, which is valid JSON and keeps only the last, and a UTF-8 byte-order mark.

**Why does "Edit Config" open a different file on Windows?**
On MSIX-packaged Windows installs, a user report describes the app reading a virtualised copy under `%LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\` while "Edit Config" opens the real `%APPDATA%\Claude\` path, with no error when the file you edited is ignored. Run `Get-AppxPackage *Claude*` to see whether you are on an MSIX build at all; the report also mentions a second package name, so do not screen on one path alone.[^msix]

**Do I need to restart Claude Desktop after editing the config?**
Yes — "completely quit Claude Desktop and restart it." Closing the window is not enough; on macOS the red close button leaves the app running.[^local][^debug]

**How do I check whether an MCP server connected?**
Click the "+" button at the bottom of the chat box and select Connectors to see connected servers and their tools; Developer settings additionally shows connection status and logs. Do not go looking for a hammer icon — current MCP instructions describe the Connectors route instead.[^debug][^extensions]

**Where are Claude Desktop's MCP logs?**
`~/Library/Logs/Claude` on macOS, `%APPDATA%\Claude\logs` on Windows. `mcp.log` covers connections and connection failures; `mcp-server-NAME.log` (written `mcp-server-SERVERNAME.log` in the docs) holds that one server's stderr. Restart the app first, then list the directory — the per-server file is created by the launch you are trying to observe.[^local]

**Why does my server run in the terminal but not in Claude Desktop?**
Stdio servers "inherit only a limited subset of environment variables automatically," and the working directory "may be undefined." Point `command` at an absolute binary path, write absolute paths in `args` (`~` is not expanded inside JSON), and put anything else the server needs — including `PATH` — in the `env` key.[^debug]

**Can logging break my MCP server?**
Yes, if it goes to stdout. Local servers "should not log messages to stdout … as this will interfere with protocol operation." Log to stderr, which the host captures for you.[^debug]

**My server connects but exposes nothing. What else could it be?**
Two things: logging to stdout, which interferes with protocol operation, and a capability mismatch. For the second, the `2026-07-28` docs say to "inspect the request's `_meta` and the `server/discover` response to verify both sides declared what you expect"; a capability the client never declared comes back as `MissingRequiredClientCapabilityError` (`-32021`). Those names are version-specific — check them against the version your server targets.[^debug]

**How do I test an MCP server outside Claude Desktop?**
`npx -y @modelcontextprotocol/inspector --cli node /abs/path/to/server/index.js --method tools/list` lists the server's tools and exits. Inspector requires Node 22.19.0 or newer and is the debugging guide's recommended first stop.[^inspector][^debug]

**My extension installed but its tools aren't available. What now?**
Restart Claude Desktop to refresh the extension registry, check the extension's configuration settings for missing required fields, and verify that any API keys or credentials were entered correctly.[^extensions]

**Can my company block local MCP servers?**
Yes. `isLocalDevMcpEnabled` is a documented Team/Enterprise policy key — Boolean, default `true`, "Enable local MCP servers" — deployed by MDM against the `com.anthropic.claudefordesktop` domain on macOS, or by Group Policy under `HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Claude` (and the HKCU equivalent) on Windows. You can read those locations yourself, but check device *and* user scope on both platforms before concluding nothing is set.[^enterprise]

**My connector is listed but Claude will not use it. Why?**
Check the per-conversation toggle under the "+" button, and the "Search and tools" menu, which lets you disable individual tools. A connector can be connected and still have the tool you want switched off.[^connectors]

**Why does my connector work on claude.ai but not in Claude Desktop?**
Remote connectors are reached from Anthropic's infrastructure on every surface, so they behave the same in both — look at per-conversation and per-tool toggles instead. Local `claude_desktop_config.json` servers are the opposite case: they run on your machine and "aren't available in Cowork or claude.ai."[^connectors]

**Does the free plan limit this?**
Free users are limited to one remote custom connector. That documented limit applies to remote connectors, not to local servers configured in `claude_desktop_config.json`.[^connectors]

## Bottom line

The causes behind an MCP server not showing up in Claude Desktop that cost the most time are the quiet ones — a config file the app never read, an app that was never actually quit, and a policy key set outside the application entirely. None of the three announces itself in the interface, so the instinct to go straight to the config is usually acting on no evidence at all.

Invert that instinct. Open the Connectors menu and see whether the server is already there. Run your config through a JSON parser. Quit the app fully, reopen it, and list the log directory — `~/Library/Logs/Claude/` on macOS, `%APPDATA%\Claude\logs` on Windows — to see whether a per-server log was created. Those three observations cost nothing, and between them they tell you which of the sections above you actually need. If no launch was attempted at all, the problem is upstream of your server, and no amount of editing `command` and `args` will surface it.

When you do change something, change one thing, quit fully, and re-read the log. And if you are building the server rather than installing one, prove it in MCP Inspector first — a server whose `tools/list` works outside Claude Desktop turns an open-ended search into an environment problem with a short list of causes.

Next steps: if you are writing your own server, our [production MCP server tutorial in TypeScript](https://nerdleveltech.com/mcp-server-typescript-oauth-streamable-http-production-tutorial) covers OAuth and Streamable HTTP end to end, and the [MCP client tutorial for stdio tools](https://nerdleveltech.com/mcp-client-typescript-stdio-tools-tutorial) shows the other half of the connection you are debugging here. If your server connects but Claude ignores its tools, that is a different problem with its own research — see [how many tools an AI agent can handle](https://nerdleveltech.com/how-many-tools-can-an-ai-agent-handle) before adding more.

[^local]: Model Context Protocol, "Connect to local MCP servers." Config paths, the Settings → Developer → Edit Config route, the `mcpServers` schema, "completely quit Claude Desktop and restart it", the check-your-syntax troubleshooting step, the suggestion to run the server manually from the command line, the Connectors UI path, log locations and file names, the absolute-paths rule, the `${APPDATA}` ENOENT case and the global-npm caveat. modelcontextprotocol.io serves versioned documentation sets and the undated URL does not always resolve to the current one, so this footnote cites the dated `2026-07-28` set, which is where every string quoted above appears. <https://modelcontextprotocol.io/docs/2026-07-28/develop/connect-local-servers>

[^debug]: Model Context Protocol, "Debugging," `2026-07-28` documentation set. Inspector as first stop, the stdout prohibition, stderr capture, the Streamable HTTP logging guidance and the `notifications/message` deprecation notice, environment-variable inheritance, undefined working directory, absolute-path guidance under "Server startup", the `env` key, "Invalid JSON syntax" under configuration errors, the Connectors status check, the Windows PowerShell log command, log contents, the `server/discover` and per-request `_meta` capability checks with error codes `-32602` and `-32021`, and the "fully quit and reopen; closing the window is not enough" rule for server code changes. The undated URL does not always resolve to this set, so the dated URL is cited. <https://modelcontextprotocol.io/docs/2026-07-28/tools/debugging>

[^inspector]: Model Context Protocol, "MCP Inspector." Three clients behind one binary, the Node 22.19.0 minimum, the web/CLI/TUI invocations, inspecting a published npm server, the CLI client's positional remote-URL form with `--transport http`, and the mode-flag rules. Cited at the dated `2026-07-28` URL: the undated one may serve an older Inspector release that documents none of these. <https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector>

[^extensions]: Anthropic Help Center, "Getting Started with Local MCP Servers on Claude Desktop," dated June 30, 2026. Extension install paths, the `.mcpb` format, the "extension appears installed but tools aren't available" and "extension configuration issues" remedies, the bundled Node.js environment, supported languages, `"sensitive": true` credential storage, update behaviour, and the "+" button → Connectors / Developer settings check. <https://support.claude.com/en/articles/10949351-getting-started-with-local-mcp-servers-on-claude-desktop>

[^connectors]: Anthropic Help Center, "Get started with custom connectors using remote MCP." Plan availability and the one-connector free limit, connections originating from Anthropic's infrastructure, the private-network and VPN consequence, the local-versus-remote boundary, the Owners-only gate on Team and Enterprise, per-conversation toggles, the "Search and tools" per-tool control, the remove-and-re-add rule, and the advanced-research limitation. <https://support.claude.com/en/articles/11175166-get-started-with-custom-connectors-using-remote-mcp>

[^when]: Anthropic Help Center, "When to use desktop and web connectors." Which mechanism suits which tool, the surface-availability table for remote connectors versus desktop extensions, and the "Plugins work with both" section. <https://support.claude.com/en/articles/11725091-when-to-use-desktop-and-web-connectors>

[^enterprise]: Anthropic Help Center, "Enterprise configuration for Claude Desktop." The policy table including `isLocalDevMcpEnabled`, `isDesktopExtensionEnabled` and `isDesktopExtensionDirectoryEnabled` with types and defaults, the `com.anthropic.claudefordesktop` macOS preferences domain, the `HKLM:\SOFTWARE\Policies\Claude` Windows registry path, machine-over-user precedence, and policy-over-allowlist precedence. <https://support.claude.com/en/articles/12622667-enterprise-configuration-for-claude-desktop>

[^msix]: anthropics/claude-code issue #26073, "[BUG] Windows MSIX: 'Edit Config' opens wrong claude_desktop_config.json — MCP servers silently fail to load," opened February 16, 2026; open and unassigned at time of writing, and carrying an `invalid` label alongside `bug`. Reported against Claude Desktop 1.1.3189.0, MSIX package `Claude_pzs8sxrjxfjjc`. A user bug report, not vendor documentation. <https://github.com/anthropics/claude-code/issues/26073>

[^msix2]: anthropics/claude-code issue #38830, "[BUG] mcpServers in claude_desktop_config.json silently ignored on Windows MSIX install (v1.1.8629.0)," opened March 25, 2026; closed, labelled `bug` and `invalid`. The reporter kept both config files in sync with valid JSON and still saw no servers load, quoting a `main.log` line reading "Error reading or parsing config file" with an unexplained `SyntaxError`. A user bug report, not vendor documentation. <https://github.com/anthropics/claude-code/issues/38830>
