Skip to main content
When an audit does not end with a score, the exit code tells you which kind of problem it hit and the last lines of the output tell you which one. Find the exit code in the table, then the message in the sections below.
Every connection failure ends with the same line, Error connecting to the MCP server: and the target. The line that names the cause is above it. Some failures also print a Python traceback from the HTTP library; its last line carries the underlying error, such as certificate is expired.
The sections are ordered by how often each outcome appeared when mcpscore audited the 13,695 remote endpoints listed in the official MCP registry in August 2026: authentication 24.6%, unreachable 9.5%, payment required 3.0%, not MCP 2.2%, no completed handshake 1.1%, rate limited 0.8%.

The server requires authentication

Symptom:
Cause: the server answered 401 or 403 without credentials. This is not an error. mcpscore scores what it can observe without a session: TLS, the WWW-Authenticate challenge and the OAuth discovery metadata. Fix: pass a credential to audit behind the gate:
A partial audit always fails --fail-under, with exit code 3, because a score from ten checks cannot demonstrate a threshold:
The whole flow, including OAuth sign-in, is in Audit a server behind auth.

The server rejected your credentials

Symptom:
Cause: you passed --token, --header or $MCPSCORE_TOKEN, and the server still answered 401 or 403. Fix: check that the token is current and has the scopes the server requires. --token sends it as Authorization: Bearer; a server that expects another header needs --header 'X-Api-Key: ...' instead.

The server is unreachable

Symptom:
Cause: the host name does not resolve, nothing listens on the port, or the TLS handshake failed. The text in parentheses says which, in your operating system’s words. On macOS: nodename nor servname provided, or not known for DNS, All connection attempts failed for a closed port, and certificate is expired or certificate is not trusted for TLS. Add -v to see the full traceback. Fix: check the URL from the same machine with curl -sS -o /dev/null -w '%{http_code}\n' https://your-server.example/mcp. If curl fails the same way, the problem is the network or the certificate, not mcpscore. A certificate error is a real finding: MCP clients refuse that server too.

The server answered with an HTTP error

Symptom:
Cause: the server answered the MCP handshake with an HTTP status other than 401 or 403. The common ones: To see what the server says to a POST, send it the request that opens a session. Servers on 2025-11-25 and earlier start with initialize:
A legacy or dual-era server answers with a JSON-RPC result that contains protocolVersion and serverInfo (Lifecycle §Initialization). A modern-only 2026-07-28 server has no initialize and may reject it. Ask it with server/discover, which every modern server implements:
A modern or dual-era server answers with supportedVersions and its capabilities (Lifecycle §Protocol Version Negotiation). If both requests fail, the endpoint is not an MCP server.

The endpoint is not an MCP server

Symptom:
A traceback above it may end in Expected response with content type 'text/event-stream', got 'text/html'. Cause: the URL answered, but not with MCP. It is usually a website, a REST API or a proxy’s error page on the right host but the wrong path. Fix: find the MCP endpoint path in the server’s docs and audit that URL. The curl request in the previous section shows what the URL returns.

The server redirected

Symptom:
Cause: mcpscore follows a redirect only when it stays on the same origin and keeps the request as sent, which is the MCP SDK’s rule too. A redirect from http:// to https://, or to another host, is not followed. Fix: audit the URL the message names. If that URL is http:// while yours was https://, the server sits behind a TLS-terminating proxy it does not trust; the message suggests the https:// form to try.

The handshake timed out

Symptom:
or Connection timeout for server: when the TCP connection never opened. Cause: the server accepted the connection and did not complete the MCP handshake within 30 seconds, or the host dropped the connection attempt. Cold-starting serverless hosts and servers that do slow work in their startup code hit this. Fix: re-run once the server is warm. If it times out every time, move slow startup work out of the initialize path.

A local server does not start

These come from --stdio and from a .py or .js target, which mcpscore launches itself. Symptom: Command not found: 'my-server'. Please ensure it is installed and on PATH. Cause: the first word after --stdio is not an executable on PATH, and not an existing file. Fix: use the full path, such as --stdio ./bin/my-server, or install the command. Symptom: 'server.py' is a script, not an executable command. Launch it with its interpreter: --stdio python server.py Cause: --stdio runs a command, and a script without a shebang and the executable bit is not one. Fix: run the command the message prints. For a Python script it also prints the uv run form to use inside a uv project. Symptom: Permission denied launching './server'. Make it executable (chmod +x) or launch it with its interpreter Cause: the file exists but is not executable. Fix: chmod +x ./server, or put its interpreter first. Symptom: Server script not found: ./server.py Cause: the .py or .js target path does not exist. Fix: check the path relative to the directory you run mcpscore from. Symptom:
Cause: the command started, and the server process exited before it answered. Every line the server writes to stderr is shown with the server stderr: prefix. Fix: read the server stderr: lines. They usually name a missing file, a missing dependency or a missing environment variable. Pass variables with --env NAME.

The command line was rejected

Symptom: the usage summary, then a line starting with Usage error:, exit code 1. For example:
Cause: a flag value or a combination of flags mcpscore cannot run. Fix: the line names the flag. --stdio takes the rest of the command line, so every mcpscore option must come before it. All flags are listed in the CLI reference.

A gate failed

Symptom: the audit completes, then Gate failed — and exit code 3:
Cause: the score, as a rounded percentage, is below --fail-under; or the readiness percentage is below --fail-under-readiness; or a rule at or above a [gate] fail_on severity failed. Fix: the failed rules are the ❌ lines above the score, each with a Fix: line. Improve your score covers the rules most servers fail. To change what the gate counts, see Configure rules. A failed --smoke check exits 4 with Gate failed — --smoke: 2 smoke check(s) failed. Smoke mode explains each check.

What’s next