---
title: "How to Troubleshoot an MCP Connection"
description: "Five failures cover almost every broken MCP connection. How to tell them apart in two commands, what fixes each one, and why the fifth never announces itself."
canonical_url: "https://builderscamp.com/guides/tools/mcp-troubleshooting-for-pms"
date_published: "2026-09-18"
date_modified: "2026-09-18"
author: "Andre Albuquerque, Guilherme Salgueiro"
publisher: "Builders Camp"
guide_class: "tools"
---

# MCP troubleshooting for product managers, five failures and how to tell them apart

**TL;DR:** Almost every broken MCP connection is one of five things: it never connected, it is not authenticated, it is registered but inactive, its output was truncated, or it worked and was wrong. Two commands tell the first three apart in under a minute. The fifth is the only one that never reports itself, which is why it deserves a deliberate check rather than a diagnostic.

## Where do you look first?

Two commands, in this order, before forming any theory.

`claude mcp list` shows every configured server and the state it is in: connected, needs authentication, failed to connect, pending approval, rejected by policy, or disabled for this project. Those states are not synonyms for broken. They are five different problems with five different fixes, and reading the state first saves you from debugging the wrong one.

`claude mcp get <name>` then gives the detail for a single server, including the HTTP status and the error text behind a failure. Inside a session, `/mcp` shows the same picture and is where re-authentication lives.

Almost everything below is one of these two commands plus a decision. The exception is the fifth failure, which neither command can see.

## Failure one: it never connected

The state reads as failed to connect, and the cause is nearly always configuration rather than the server.

For a remote server, the most frequent error is a URL with no transport declared alongside it, which surfaces as a complaint about a url with no type. Adding a type of http, or sse or ws where the server uses one of those, fixes it. Beyond that, check the URL is reachable and the credentials are current.

For a local server, confirm the command exists and is executable on your machine. A local server is a program being launched, so a missing runtime or a typo in the package name produces the same failure as a broken URL does remotely.

Two quieter causes are worth knowing because they look like nothing. Claude Code warns about hidden whitespace in configuration values, leading or trailing spaces that are invisible in an editor and fatal in a URL. It also warns about environment variable references that point at a variable which does not exist, and about reserved server names that collide with built-ins. If the server is slow to start rather than broken, the startup timeout is adjustable with the `MCP_TIMEOUT` environment variable.

## Failure two: it connected but is not authenticated

The state reads as needs authentication, or a tool call returns a 401 or a 403. This is the most common recurring failure, because it is the only one that arrives on its own: tokens expire, and a connection that worked last Thursday can be in this state on Monday with nothing having changed on your side.

The fix is `/mcp`, select the server, re-authenticate, or `claude mcp login <name>` from the command line. `claude mcp logout <name>` clears stored credentials when you want a clean start.

One trap here wastes real time. Certain credential variables are deliberately blocked from expanding inside a remote server's URL and headers, including `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `AWS_BEARER_TOKEN_BEDROCK`, `HTTPS_PROXY` and `NPM_TOKEN`. They do not error. They read as empty, so the header goes out blank and the server answers with an authentication failure that looks like a wrong key. Copying the value into a custom variable name and referencing that resolves it.

## Failure three: it is registered but not active

Here the server is fine and something is deliberately holding it back, which is why the states are distinct rather than lumped under failure.

Pending approval means a project-scoped server from `.mcp.json` is waiting for you to approve it in an interactive session. Rejected means a policy setting is blocking it. Disabled for this project means someone turned it off through `/mcp`. A strict configuration flag loads only servers passed explicitly and ignores everything else.

Scope collisions belong in this group too. The same server name registered at more than one scope resolves by precedence, running local first, then project, then user, then plugin-provided servers, then claude.ai connectors. Claude Code warns when it sees one name in several scopes pointing at different endpoints, and that warning is easy to scroll past while assuming your newest edit is the one in effect.

## Failure four: it worked, and the output was cut off

MCP tool output is capped on purpose. Claude Code warns at 10,000 tokens, caps at 25,000 by default, and has a hard ceiling of 500,000 characters. When output goes over, it is written to a file and replaced in context with a reference to that file, so nothing is lost and nothing is available to reason over either.

`MAX_MCP_OUTPUT_TOKENS` raises the cap. Narrowing the question is usually the better move, because a request that returns 30,000 tokens of raw records is a request for a data dump rather than an answer, and the model has to read it all back to you. Long-running tools are a separate case with their own controls: a per-server timeout in the configuration and an idle timeout environment variable for tools that keep working without producing output.

## Failure five: it worked, and it was wrong

This one never reports itself, which is what makes it the expensive one.

Four causes account for most of it. The permission behind the connection is narrower than you assumed, so a query returns nothing and an empty result is indistinguishable from a genuine zero. The tool list changed on the server side, which the protocol explicitly allows, and a cached discovery result means what runs is not what you last looked at. The model chose a different tool than the one you had in mind, reasonably, because two tools had similar descriptions. Or the underlying definitions disagree, and the connection faithfully reported a number built on the wrong one.

The only reliable detection is to ask. Which tool did you call, with which arguments, against which project. Then check that against what you meant. Doing this on the first three answers from any new connection is worth more than any amount of configuration care, because it is the only step that catches a system which is working exactly as configured and answering the wrong question.

There is a security-flavoured version of the same failure worth naming: the protocol's own guidance treats tool descriptions as untrusted unless the server is trusted, so a server behaving unexpectedly is not always a bug. [Claude Code permissions and safety](https://builderscamp.com/guides/tools/claude-code-permissions-and-safety) covers where the approval boundary sits around tool calls.

## What to do before the next connection

Three habits close most of the gap. Verify with `claude mcp list` immediately after adding anything, rather than discovering at use time that a server never started. Prefer the read-only path where the vendor publishes one, as Linear does with a separate read-only endpoint, so a misconfiguration cannot write. And test every new connection on a question whose answer you already know.

That last habit is the one Builders Camp's Building with Claude Code bootcamp generalises into a system: its practical challenge is built around a team whose AI-assisted workflow broke because nobody had defined what done meant, and the exercise is designing the operating model that would have caught it automatically. It runs 1 week with 2 live sessions and 9 microlessons under Guilherme Salgueiro, alongside AI Agents on the design side, both inside the AI Agentic Builders Expert Track.

[See the Building with Claude Code bootcamp](https://builderscamp.com/bootcamps/building-with-claude-code?utm_source=guide&utm_medium=organic&utm_campaign=mcp-troubleshooting-for-pms)

If you are still setting up rather than fixing, [MCP setup for product managers](https://builderscamp.com/guides/tools/mcp-setup-for-product-managers) covers the two routes and the scope decision, and [MCP for product managers](https://builderscamp.com/guides/tools/mcp-for-product-managers) covers what the protocol is doing underneath all of this.

## Frequently asked questions

### What is the first command to run when something is wrong?

claude mcp list, which shows every configured server and its state: connected, needs authentication, failed to connect, pending approval, rejected or disabled. Then claude mcp get <name> for the failing one, which returns the detail including HTTP status and error text. Inside a session, /mcp shows the same states.

### What does the error about a url but no type mean?

A remote server entry needs a transport declared alongside its URL. Adding a type of http, or sse or ws where the server uses those, resolves it. It is the most common configuration error because the URL alone looks complete.

### Why does my API key seem to be ignored?

Some variables are deliberately blocked from expanding inside a remote server's url and headers, including ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, AWS_BEARER_TOKEN_BEDROCK, HTTPS_PROXY and NPM_TOKEN. They read as empty rather than failing loudly. Copy the value into a custom variable name and reference that instead.

### The server says it needs authentication. What now?

Run /mcp, select the server and choose re-authenticate, or run claude mcp login <name> from the command line. Tokens expire, so a server that worked last week can land in this state with nothing else having changed. claude mcp logout <name> clears the stored credentials if you need to start clean.

### Why is a server in the project config not loading?

Project-scoped servers from .mcp.json need approval in an interactive session and sit in a pending-approval state until you give it. They can also be blocked by the disabledMcpjsonServers setting, disabled for the project through /mcp, or excluded by the strict MCP config flag. Each of those shows as a distinct state rather than as a failure.

### Why did a working tool call come back cut off?

MCP output is capped: Claude Code warns at 10,000 tokens and caps at 25,000 by default, with a hard ceiling of 500,000 characters. Oversized output is saved to a file and replaced with a reference to it. Raising MAX_MCP_OUTPUT_TOKENS works, and narrowing the question usually works better.

### How do I catch the failure where everything looks fine but the answer is wrong?

Ask the assistant which tool it called and with which arguments, then check that against what you meant. Most wrong answers are correct answers to a slightly different question, and an empty result from a permission you do not have looks identical to a genuine zero.

## Sources

- [Claude Docs: Connect Claude Code to tools via MCP](https://code.claude.com/docs/en/mcp)
- [Model Context Protocol: Architecture overview](https://modelcontextprotocol.io/docs/learn/architecture)
- [Model Context Protocol: Security best practices](https://modelcontextprotocol.io/specification/2026-07-28/basic/security_best_practices)
- [Linear: Model Context Protocol](https://linear.app/docs/mcp)

## How this guide was made

Researched from Builders Camp's bootcamp, track and masterclass material and the sources listed on this page, drafted with AI, and fact-checked against every source cited.
