Troubleshooting
The client says the server is unreachable
But the URL works, and the connection test in the admin panel is green.
Why this one is confusing
Every obvious check passes. The URL opens in a browser, the Connection Test in the admin panel reports everything healthy, and the token was generated minutes ago. Yet the MCP client insists it cannot reach the server.
In most of these cases the request is arriving perfectly well. What is missing is the credential, because the web server removed it before PHP ever saw it.
Identify it in ten seconds
Run this from any machine. Replace the URL with your own endpoint and the token with your real token.
curl -s -X POST https://example.com/modules/addons/mx_mcp/mcp.php \
-H "Authorization: Bearer THE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'The response identifies the failure precisely:
| Response contains | What it means | What to do |
|---|---|---|
Invalid API credentials | The header never arrived. Your server is stripping it. | Go to "The header is being stripped" below. |
Invalid bearer token | The header arrived. The token itself is wrong or was revoked. | Generate a new token in the admin panel. |
A result with serverInfo | The endpoint is authenticating correctly. | The problem is in the client configuration. |
An HTML page | The URL is wrong, or the server returned an error page. | Check the URL, including any subdirectory. |
The distinction between the first two responses is the whole diagnosis. They come from different branches of the endpoint. If you sent a correctly formed Bearer header and still got Invalid API credentials, the header did not survive the trip.
The header is being stripped
Apache uses the Authorization header for its own authentication, so by default it consumes the header instead of passing it to PHP. Custom headers are unaffected, because the server has no reason to claim them.
MX MCP ships an .htaccess in its module directory that works around this. If that file is not being applied, the workaround never runs.
Check whether it is being applied
curl -s -o /dev/null -w "%{http_code}\n" \
https://example.com/modules/addons/mx_mcp/hooks.php- 403 means the file is working. The cause is elsewhere.
- 200 means it is not being applied. That is your problem.
Fix 1: restore the .htaccess
Check that modules/addons/mx_mcp/.htaccessexists on your server. The name begins with a dot, so extraction tools and FTP clients often hide it and skip it silently on upload. If it is missing, re-upload it from the release package. It ships in every release.
If the file is present and the check above still returns 200, your host has AllowOverride None and ignores .htaccess files entirely. Ask them to enable overrides for that directory, or to add this to the vhost:
CGIPassAuth OnCGIPassAuth requires Apache 2.4.13 or newer and is the more reliable option on PHP-FPM and CGI setups.
Fix 2: use API Key credentials
This needs no server changes and is the faster route when your host will not adjust the configuration. The endpoint accepts a second credential type that travels in custom headers, which are never stripped.
- In Addons > MX MCP > API Keys, create a credential and choose the API Key type instead of Bearer Token.
- Copy the key and the secret.
- Configure your MCP client with both headers instead of Authorization.
{
"mcpServers": {
"whmcs": {
"type": "streamable-http",
"url": "https://example.com/modules/addons/mx_mcp/mcp.php",
"headers": {
"X-API-Key": "your-key",
"X-API-Secret": "your-secret"
}
}
}
}What your client shows instead
MCP clients rarely report this as an authentication problem, which is what makes it hard to place. Both clients below respond to a 401 by attempting OAuth discovery, and then report that failed probe rather than the original rejection.
| Client | Message shown |
|---|---|
| Cursor | Server not found. Please check the URL |
| Claude Desktop | Connection or OAuth errors after a 401 |
Why the connection test still passes
The Connection Test in the admin panel runs inside your server and calls the handler directly. It never makes an HTTP request through Apache, so it never carries an Authorization header and cannot observe one being stripped. A green result confirms the handler, the database and the session layer are healthy. It does not confirm that an external client can authenticate.
Still not connecting?
Send us the output of the first command on this page. It separates the possible causes in one step, which is faster than sending client logs.