Michał Jonik
2026-08-29

The path is /mcp, or the connector goes silent

I run a small MCP server that gives AI assistants access to my notes. It sits in a container on the NAS at home, behind a Cloudflare Tunnel, and three clients use it: the claude.ai connector, Codex and Claude Code.

Claude Code worked from day one. The other two went through the whole OAuth flow, received a token and then did nothing. The server logged one authenticated request and after that, silence. The client never sent the message that finishes the MCP handshake, and its UI said only that authorization had failed. Nothing on my side reported an error.

That went on for weeks, and the fix turned out to be one environment variable.

Five theories, five measurements

  1. Cloudflare Access is in the way. On the first evening I tried three Access setups, one after another: my own OAuth behind Access, then Cloudflare’s managed OAuth, then moving authentication to the server itself. Each change had a sensible reason and each one left the symptom exactly as it was. A service token in the Access policy returned the same 401 with or without the token.

  2. The edge rewrites the metadata. An Access application of type mcp replaces /.well-known/oauth-protected-resource with its own version. I compared the response through Cloudflare with the one straight from the server, changed the application type, and the metadata matched. The clients stayed silent.

  3. A client-side heuristic. Reports in Anthropic’s tracker, such as #784, describe the connector entering an OAuth flow because of what the metadata says rather than what the server requires. What settled it was the test in point 5: with no authorization server announced, the connector failed the same way.

  4. A bot-blocking rule at the edge. Cloudflare’s “Manage AI bots” rule produces exactly this picture: a bare 403 that the server never sees. I sent requests with different user agents: Claude-Web got 403, Claude-User, the one the connector uses, went through. A request from my own address is not the same as traffic from Anthropic’s servers, so this proved less than it seemed. What ruled the rule out was the fix: it worked without touching it.

  5. A bug in the server or the protocol. I wrote a script that runs the full handshake (initialize, the initialized notification, tools/list) against the public address. It passed. I also stopped the server from advertising OAuth at all, with the endpoint still requiring a bearer token, and the failure looked the same. The server was healthy, so the problem was in what the clients expected from it.

The fix

The answer was in anthropics/claude-ai-mcp#878. Its author kept the host, the authorization server and the identity the same and changed only the endpoint path. The connector worked on /mcp and failed on every other path, while other clients connected to all of them. Issue #690 has more reports of the same symptom, from people who arrived at the same fix. The symptom in #878 differs slightly from mine: no request at all after the token, where my server saw one.

My server listened on /. Its maintainers had moved it there to make it work better with the connector. I set VAULT_MCP_PATH=/mcp, changed the URL in both clients, and both of them started working that day. Codex too, even though I had earlier put its failure down to a separate known bug because the log looked similar. Why the change fixed Codex I do not know. According to #878, other clients work on any path, so moving away from / may matter more for it than /mcp itself.

The same OAuth flow on / and on /mcp: on / the client goes silent after the token, on /mcp it completes the handshake

Anthropic has not confirmed this as a documented requirement. It is a dependency observed in the tracker and in my measurements, so treat the path as part of the client contract and check it again when the client changes.

While chasing the theories I had forked the server and added five patches. None of them was needed, and I went back to the clean upstream release.

What I check first now

When an integration fails without saying why:

  • Prove the server is healthy with your own script that runs the full handshake through the public address. One passing run rules out a whole branch of theories.
  • Rule out one layer at a time with a flag. Switching off the OAuth advertisement took a minute and answered a question that two rebuilds of the Access configuration had not.
  • Read the vendor’s issue tracker before changing the architecture. Someone may have already isolated the variable.
  • Matching the signature of a public issue does not make it your cause. Measure your own traffic.

What carries over to a company

AI agents in a company reach systems through a chain of intermediaries: an identity provider, a WAF, a gateway, a proxy, the server. When the client fails silently, every team in that chain can show that its own part works, and each of them is right. Agree up front on what each client requires (path, transport, authentication mode) and write it down per client, the same way you would for any other integration contract, with the URL in it.

Update, October 2026: in #1126 and #690, a collaborator from Anthropic attributed the same symptom (token issued, then silence) to a 403 from a Cloudflare WAF or bot rule in front of the endpoint, including on servers that already use /mcp. The path is necessary but not always enough. If it is already /mcp, check the security events at the edge.

mcpclaudecodexcloudflaredebugging