---
title: MCP server won't connect? How to test it with the MCP Server Checker
description: Claude, Cursor or another AI client says it can't connect to your MCP server, and opening the URL in a browser shows an error that may or may not be normal. To test an MCP server, run the protocol's initialize handshake and list its tools, the way a client does. Here's how with the free MCP Server Checker, why a 405 in the browser is expected, and the curl commands that reproduce each step.
canonical: https://watchfor.io/blog/how-to-test-an-mcp-server
---

# MCP server won't connect? How to test it with the MCP Server Checker

2026-10-04 · WatchFor Team · Guides · guides, mcp, ai

Claude, Cursor or another AI client says it can't connect to your MCP server, and opening the URL in a browser shows an error that may or may not be normal. To test an MCP server, run the protocol's initialize handshake and list its tools, the way a client does. Here's how with the free MCP Server Checker, why a 405 in the browser is expected, and the curl commands that reproduce each step.

To test an MCP server, do what an AI client does: send a JSON-RPC
`initialize` request to its endpoint over Streamable HTTP, check that it
answers with a protocol version and capabilities, then call `tools/list`
and confirm the tools you expect are there. If the handshake works from
outside your network, the server is fine and the problem is in the client's
configuration. If it fails, the error says which step broke.

The free [MCP Server Checker](/mcp-server-checker) runs that handshake and
the tool listing from a WatchFor probe location and shows the server's name,
protocol version, capabilities, timings and full tool inventory. No signup.

## What this tool answers

*Does this MCP endpoint complete a real handshake, and which tools does it
expose?* Reach for it when an AI client reports "failed to connect" or
shows zero tools, after deploying a remote MCP server behind a proxy or
serverless platform, before you share an endpoint with users, or when you
want to see what a third-party MCP server offers before connecting an agent
to it.

## A real example

### Testing an MCP server when the client says it can't connect

A common first step when a client won't connect: open the endpoint in a
browser. That gives a confusing result. We tried it on Cloudflare's public
documentation server, `https://docs.mcp.cloudflare.com/mcp`, which needs no
authentication:

- A plain `GET` returns **405 Method Not Allowed**.
- A `POST` without the right `Accept` header returns **406 Not Acceptable**
  with the message "Client must accept both application/json and
  text/event-stream".

Both look like failures, and neither is one: this server takes JSON-RPC
over `POST` only and insists on the headers the spec requires. A browser
test can't tell you whether the server works. So we ran the
[MCP Server Checker](/mcp-server-checker) on the same URL:

![The MCP Server Checker after checking https://docs.mcp.cloudflare.com/mcp from Vilnius: Online, Handshake OK, protocol 2025-06-18, capabilities prompts and tools, server docs-ai-search v0.4.13, 2 tools, 1 prompt, handshake 20 ms, tools list 13 ms, total 51 ms, and a tool inventory of search_cloudflare_documentation and migrate_pages_to_workers_guide](/blog/how-to-test-an-mcp-server-result.webp)

**Online, handshake OK.** The server agreed to protocol version
`2025-06-18`, advertised `prompts` and `tools`, and identified itself as
`docs-ai-search` version 0.4.13. It listed **2 tools** and 1 prompt. The
`initialize` step took 20 ms, `tools/list` 13 ms, and the whole check
51 ms. The inventory shows each tool with the description an agent reads:
`search_cloudflare_documentation` and `migrate_pages_to_workers_guide`.

**The answer:** the server is healthy; the 405 and 406 were the server
correctly rejecting requests that weren't MCP. When your own client can't
connect but the checker succeeds, look at the client side: the exact URL
(including the `/mcp` path), whether the client supports Streamable HTTP
rather than only the older SSE transport, and any auth header it is
supposed to send.

## How to read the results

| What you see | What it means |
| --- | --- |
| **Online / Failed** | Whether the `initialize` handshake completed. |
| **Handshake OK / failed** | The same verdict as a badge. |
| **Protocol version** (e.g. `2025-06-18`) | The MCP spec revision the server agreed to. A client that only speaks an older revision may refuse it. |
| **Capability badges** | What the server advertises: `tools`, `prompts`, `resources`, `logging` and so on. |
| **Endpoint** | The URL that was tested. |
| **Server** | The name and version from the server's `serverInfo`. Useful to confirm a deploy actually rolled out. |
| **Tools / Resources / Prompts** | How many of each the server listed. Resources and prompts are counted only when advertised. |
| **Handshake / Tools list / Total** | How long `initialize`, `tools/list` and the whole check took. A slow handshake with a fast tool list often means a cold start. |
| **Tool inventory** | Every tool's name and the start of its description, exactly what an agent will read. |
| **Error** | On failure, what went wrong: a 401/403 means auth is required, 404 a wrong path, a timeout a server that never answered. |

## More ways to use it

- **After a deploy.** Confirm the new version string and that the tool
  count didn't drop to zero.
- **Behind a proxy or CDN.** Make sure `POST` bodies and the
  `text/event-stream` response pass through; buffering proxies can break
  streamed replies.
- **Reviewing a third-party server.** Read every tool description before
  you connect an agent. They are instructions the model will see.
- **Comparing environments.** Run staging and production and compare the
  tool lists and protocol versions.

## Tips and gotchas

- **Public, unauthenticated servers only.** The checker sends no tokens, by
  design. A server that requires OAuth or a bearer token reports a 401 or
  403 handshake failure, which at least proves the endpoint is reachable.
- **Streamable HTTP only.** Servers that run over `stdio` are local
  processes and can't be reached from the internet at all.
- **Read-only.** The checker never calls a tool, so it can't trigger side
  effects.
- **Twelve-second budget.** A server on a serverless platform that takes
  longer to wake up reads as a timeout. Run it twice; a fast second run
  points to a cold start.
- **One moment, one location.** The probe nearest to you runs the check
  over IPv4.
- **Tool descriptions can change.** An inventory that looks fine today can
  be edited after you've connected. [MCP server
  monitoring](/blog/mcp-server-monitoring) explains why that matters.

## Check it from the command line too

The handshake is one `POST`. Note the `Accept` header: without both types
the server answers 406.

```bash
curl -s -i https://docs.mcp.cloudflare.com/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}' \
  | grep -iE '^(HTTP|content-type|data)'
```

```text
HTTP/2 200
content-type: text/event-stream
data: {"result":{"protocolVersion":"2025-06-18","capabilities":{"tools":{"listChanged":true},"prompts":{"listChanged":true}},"serverInfo":{"name":"docs-ai-search","version":"0.4.13"}},"jsonrpc":"2.0","id":1}
```

The reply arrived as a server-sent event (`data:` line), one of the two
response formats the spec allows. List the tools the same way:

```bash
curl -s https://docs.mcp.cloudflare.com/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
  | sed -n 's/^data: //p' | jq -r '.result.tools[].name'
```

```text
search_cloudflare_documentation
migrate_pages_to_workers_guide
```

And the two "errors" from the browser test:

```bash
curl -s -o /dev/null -w '%{http_code}\n' https://docs.mcp.cloudflare.com/mcp
curl -s https://docs.mcp.cloudflare.com/mcp -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'
```

```text
405
{"jsonrpc":"2.0","error":{"code":-32000,"message":"Not Acceptable: Client must accept both application/json and text/event-stream"},"id":null}
```

This server answered without a session ID. Servers that return an
`Mcp-Session-Id` header on `initialize` expect it on every following
request, so add `-H 'Mcp-Session-Id: <value>'` to the `tools/list` call.

## Keep watching it

An MCP server can return HTTP 200 and still be broken for every agent. An
[MCP monitor](/mcp-monitoring) runs the same handshake on a schedule,
alerts when it fails or when the server exposes no tools, and records a
diff whenever a tool is added, removed or its description or schema
changes, with an optional rule that fires if the negotiated protocol
version changes. It can send a bearer token for protected servers.

## FAQ

**How do I test if my MCP server is working?**
Send an `initialize` request with `curl` (as above) or run the free MCP
Server Checker, then check that `tools/list` returns the tools you expect.
Opening the URL in a browser isn't a valid test.

**Why does my MCP endpoint return 405 Method Not Allowed?**
Because you sent a `GET`. Streamable HTTP servers take JSON-RPC messages as
`POST`; some also accept `GET` for a server-to-client event stream, many
don't. A 405 on `GET` is normal.

**Why does my AI client show no tools from my MCP server?**
Either the handshake fails (check the URL, transport and auth), or the
server initializes but returns an empty `tools/list`, often a deploy or
configuration problem. The checker shows which of the two it is.

---

Canonical page: https://watchfor.io/blog/how-to-test-an-mcp-server · All articles: https://watchfor.io/blog/all.md · Site guide: https://watchfor.io/llms.txt
