TL;DR: `Access denied for user` means the MySQL MCP server is sending the wrong username or password, or the user is not allowed to connect from the client's host. Test the exact credentials with the `mysql` CLI, fix `MYSQL_USER` / `MYSQL_PASS` in the client config `env` block, restart.

```text
ER_ACCESS_DENIED_ERROR: Access denied for user 'appuser'@'YOUR_HOST' (using password value YES)
```

## Fix it

1. Test the credentials outside the MCP layer with the exact same values:

```bash
mysql -h YOUR_MYSQL_HOST -u appuser -p'yourpassword' -e "SELECT 1;"
```

   Expected: `1`. If this fails, the problem is the credentials or grants, not the MCP server.

2. Check the host part. `'appuser'@'YOUR_HOST'` and `'appuser'@'%'` are different MySQL users. If the MCP server connects over TCP from another host, the user needs a matching host entry:

```sql
CREATE USER 'appuser'@'%' IDENTIFIED BY 'yourpassword';
GRANT SELECT ON mydb.* TO 'appuser'@'%';
FLUSH PRIVILEGES;
```

3. Update the client config `env` block:

```json
{
  "env": {
    "MYSQL_HOST": "YOUR_MYSQL_HOST",
    "MYSQL_PORT": "3306",
    "MYSQL_USER": "appuser",
    "MYSQL_PASS": "yourpassword",
    "MYSQL_DB": "mydb"
  }
}
```

4. Restart the MCP client.

   Expected: the server connects and tools work.

## When to use this

- Every tool call fails with `ER_ACCESS_DENIED_ERROR`.
- The mysql CLI with the same credentials also fails (proves it is credentials, not MCP).

## When NOT to use this

- The error is `ER_BAD_DB_ERROR: Unknown database`. Auth worked; the database name is wrong.
- The error is `ECONNREFUSED`. The server is unreachable.
- The error mentions `caching_sha2_password`. That is an auth-plugin problem, different fix.

## Compatibility

- benborla/mcp-server-mysql (MYSQL_HOST/PORT/USER/PASS/DB env config).
- MySQL 5.7, 8.x, MariaDB.

## Why it happens

MySQL authenticates the pair of (username, host), not just the username. MCP configs get copied between machines, so the password is right but the host the server connects from does not match any grant. The `(using password value YES)` detail tells you a password was sent; the fix is aligning the user, password, and host grant.

## Edge cases

- Special characters in MYSQL_PASS inside JSON need JSON escaping. A `#` or `!` is fine; a `\` or `"` needs escaping.
- MySQL 8 defaults to `caching_sha2_password`. Old clients fail with a plugin error, not access denied. If you see the plugin named, that is your problem instead.
- Skip-name-resolve servers: use IP addresses in host grants, not hostnames.