Skip to main content
Start here if the server won’t connect or a tool call fails. Each entry names the symptom and the fix.

Connection

The server cannot reach the Dashboard and tool calls return connection errors. Test each layer in order.Verify the URL responds:
A 200 response means WordPress REST is reachable. Then test authentication:
This should return your user profile. Finally test the Abilities API:
If only the last step fails, the MainWP Abilities API is not available on the Dashboard; check that your MainWP Dashboard is version 6.0 or later and up to date.
UNABLE_TO_VERIFY_LEAF_SIGNATURE or similar. For production, fix the certificate: install the full chain, match the domain, check expiration. For local development with self-signed certificates only, set "skipSslVerify": true.
The server blocks HTTP URLs because credentials would travel unencrypted. Configure HTTPS on your Dashboard. If you are intentionally running HTTP in local development, set "allowHttp": true.
The Dashboard is unreachable from the machine running your AI client. Check that the URL and port are right, the Dashboard is up, and no firewall or VPN sits in the way. Testing with the server’s IP address instead of the hostname isolates DNS problems.

Authentication

The username must match exactly (it is case-sensitive) and must be the user that owns the Application Password. If in doubt, regenerate the password; it works with or without the display spaces. Some security plugins (Wordfence, iThemes Security) disable Application Passwords, and some 2FA plugins interfere even though Application Passwords normally bypass 2FA.
Authentication worked but the WordPress user lacks the capabilities for that operation. Give the user the administrator role, or at minimum the capabilities the operations need.
Expected. MAINWP_TOKEN bearer authentication fails against the WordPress Abilities API, which authenticates through native WordPress. Configure MAINWP_USER and MAINWP_APP_PASSWORD with an Application Password instead.

Tool errors

Check the spelling; tool names use underscores (list_sites_v1, not list-sites-v1). If the name is right, the tool may be hidden by your allowedTools/blockedTools configuration, or the ability may not exist on your Dashboard version.
Safe mode is on and the AI attempted a destructive operation. That is safe mode doing its job. If you actually want destructive operations, set "safeMode": false.
Destructive tools use a two-step flow: preview, then your approval, then execution. If the AI is not following it, ask explicitly: “Show me what will be deleted first.” For unattended automation where you have verified the targets, disable with "requireUserConfirmation": false.

Confirmation flow

The AI tried to execute a destructive operation without a valid preview: no preview requested, a token that was already used (tokens are single-use), or a token bound to different arguments. Usually an AI behavior slip. Rephrase: “Show me what will be deleted first, then I’ll confirm.”
Not an error. The ability requires confirmation but cannot produce a dry-run preview, so there is nothing to show. The response still carries a confirmation token; the AI should describe what the operation will do and wait for your explicit approval before confirming.
More than 5 minutes passed between the preview and your confirmation. Say “yes, proceed” again and the AI will fetch a fresh preview.
The AI sent user_confirmed: true and dry_run: true together. They mean opposite things (execute vs. preview only); it should send one or the other.
The ability is classified destructive but its schema declares no usable confirm parameter, so the confirmation flow cannot run and the server refuses to execute. The built-in deletion tools all declare confirm and never hit this. If a third-party ability triggers it, fix its annotations on the Dashboard side, or manage it explicitly with allowedTools/blockedTools.

Resource limits

Cumulative response data crossed maxSessionData. Restart the MCP server to reset the counter, raise the limit, or use narrower queries and pagination.
A single response crossed maxResponseSize. Raise the limit or reduce the response with filters (status filters, lower per_page).
Too many API calls in one minute. Wait and retry, or raise rateLimit. Setting it to 0 disables limiting and is not recommended in production.

Configuration

The server checks ./settings.json (its working directory), then ~/.config/mainwp-mcp/settings.json. Confirm the file is where the server runs from and is valid JSON: cat settings.json | jq .
Variables must be exported (export MAINWP_URL="https://..."), names are case-sensitive, and values should not carry nested quotes. Remember that per-tool env blocks in your AI tool’s config override settings.json values.
First: validate the config file’s JSON and restart the host; most cases end there. Client-specific checks: for Claude Desktop, confirm the config file path for your OS; for Claude Code, check ~/.claude.json; for VS Code, you need version 1.101+, an open workspace (not a lone file), and Agent Mode enabled. Config locations for every client are on Connect Your AI Client.If you only see mainwp_get_setup_status and mainwp_configure, the server started without a Dashboard URL or credentials and is in setup mode. See First-run setup.
You asked your assistant to reconnect the server, or to set it up with a new Application Password, and mainwp_configure refused with a message saying the server already has credentials loaded.This is deliberate, not a bug. Chat-based setup connects a server that has no connection yet; it never overwrites one you configured yourself. The full reasoning is on the Configuration Reference, but the short version is that an assistant acts on text it is given, and text can carry instructions from places you did not intend, so a server that can be repointed from a conversation is a server that can be repointed at someone else’s Dashboard.What to do depends on why the connection is failing.The Dashboard was down, restarting, or briefly unreachable. Ask your assistant to check the connection again, which calls mainwp_get_setup_status. That retries with the credentials the server already has and connects as soon as the Dashboard answers. Nothing else is needed.The stored password is wrong, most often because you rotated it. Retrying will not help here, because it reuses the same password the Dashboard is already refusing. Update it yourself:
  1. In WordPress, go to your profile page and create an Application Password, or copy the new one you already created.
  2. Put it wherever this server reads its credentials from. That is either the env block of the server’s entry in your MCP client config, or ~/.config/mainwp-mcp/settings.json. If both exist, the environment wins.
  3. Restart your MCP client so the server picks it up.
You want to point the server at a different Dashboard. Same as above: edit the URL and credentials where they are configured, then restart the client.If the server has no credentials at all, none of this applies and chat-based setup works normally; ask your assistant to set up the MainWP connection and it will walk you through it.

Debugging

For hands-on debugging, run the server directly and watch stderr:
A healthy server prints startup messages to stderr and then waits silently for MCP commands on stdin. If you have cloned the repository, npm run inspect opens the MCP Inspector, a web interface for listing tools, executing them with custom arguments, and viewing raw request/response data. Still stuck? Open an issue on GitHub with the stderr output and your configuration (with credentials removed).