mysql-client
A Claude Code and Codex plugin that makes the assistant an effective, safe user of the Linux mysql (mysql-client) CLI against MySQL or MariaDB servers. Read-only-first by design — it teaches investigation, not modification.
Quick start
/plugin marketplace add aeresov/claude-plugins
/plugin install mysql-client@aeresov-claude-plugins
/mysql-client:setup # optional — configure connection discovery (see below)
Then ask the assistant to do something against a MySQL/MariaDB database. As long as the request fits "connect, look, summarise" (rather than "alter, migrate, drop"), the skill picks it up.
Run /mysql-client:doctor any time for a read-only health check of the setup.
Codex
Register this repository and install mysql-client:
codex plugin marketplace add aeresov/claude-plugins
codex plugin add mysql-client@aeresov-codex-plugins
Use $mysql-client:mysql-client-setup and $mysql-client:mysql-client-doctor in a Codex prompt. The main skill is $mysql-client:mysql-client. Both clients use the same skills, implementation and (where applicable) gitignored .claude/ project settings. These workflows need local execution with the prerequisites below. No global Codex configuration is changed by cloning this repository.
Claude registers the named subagent described below. Codex reads the same procedure, delegates through its available subagents when possible, and otherwise follows it inline. Claude-specific model/tool declarations do not carry over to Codex.
Prerequisites
- The
mysqlCLI binary onPATH. Debian/Ubuntu:apt install mysql-client(ordefault-mysql-client/mariadb-client). - A way to authenticate that doesn't put the password on the command line. Pick one:
- MySQL — a login-path:
mysql_config_editor set --login-path=<name> --host=<h> --user=<u> --password(prompts). - MySQL or MariaDB — a
~/.my.cnfwith a[client]section (chmod 600). - Any — a
--defaults-file=<path>your script produces from a secret store.
- MySQL — a login-path:
- For RDS / Aurora / any TLS-required server, the appropriate CA bundle for
--ssl-mode=VERIFY_IDENTITY.
See skills/mysql-client/references/connecting.md for the full credential-source guide.
Connection discovery (optional)
/mysql-client:setup configures this interactively — it asks where the project's connection URL comes from, writes .claude/mysql-client.local.md, and updates .gitignore. Or drop the file in by hand: a connection_cmd frontmatter field whose stdout is a mysql:// (or mariadb://) URL — a build target, a vault read, AWS Secrets Manager, SOPS, 1Password. The plugin runs the command, converts the URL to a [client] INI with its bundled converter, writes it to a mode-600 file at a unique temporary path in a private directory ($XDG_RUNTIME_DIR/mysql-client/, or ~/.cache/mysql-client/ where that isn't set), runs mysql --defaults-file=<that file>, and deletes it after the turn. The URL — password and all — never enters the conversation transcript.
Minimum file:
---
connection_cmd: make infra-mysql-url ENV=dev
---
Add .claude/*.local.md to .gitignore.
URL format, connection_cmd examples, and how the converter works: skills/mysql-client/references/local-settings.md.
What triggers the skill
The skill loads when you ask the assistant to:
- Connect to a MySQL/MariaDB database (e.g. "use the
prod-readerlogin-path and …"). - Inspect schema (
SHOW,INFORMATION_SCHEMA, "what tables …", "how do X and Y relate"). - Run a
SELECTor read its output. - Read
EXPLAIN/EXPLAIN ANALYZEoutput, or diagnose a slow query. - Look at
SHOW PROCESSLIST, the slow log,performance_schema, replication state.
It does not fire on requests for migrations, schema changes, DML, server admin, or non-MySQL databases.
What's in scope vs out
| Scope | In / Out |
|---|---|
| Read-only schema inspection | In |
Safe SELECTs, EXPLAIN, slow-query diagnosis | In |
--safe-updates, login-paths, output formats | In |
| Replication / performance_schema / processlist reads | In |
CREATE / ALTER / DROP / TRUNCATE | Out |
INSERT / UPDATE / DELETE / REPLACE | Out |
mysqldump, mysqladmin, users/grants, backups | Out |
| Driver/library code (Python, Node, Go, …) | Out |
| Postgres, SQLite, Redis, anything-not-MySQL | Out |
If the request crosses an "out" line, the skill names what it can't do and hands it back to you with the proposed statement spelled out — never quietly runs it.
The mysql-investigator subagent
For investigations that need many mysql calls — schema mapping across tables, slow-query root-causing, replication-lag triage, performance_schema digest analysis — the skill dispatches a read-only subagent that does the work in an isolated context and returns a focused writeup.
The subagent has no file-editing tools (only Bash, Read, Grep, Glob), and its instructions refuse writes. That refusal is instruction-level, not enforced by Claude Code: with Bash it could run a write statement or touch files. Real protection comes from the database side — connect with a read-only database user (a SELECT-only grant, plus PROCESS / performance_schema reads if you want perf triage), which the server enforces whatever the client sends. Don't pre-approve Bash(mysql *) on the assumption that the subagent can't write.
See the shared investigation procedure and the Claude agent wrapper.
Reference index
Loaded on demand by the assistant as each step requires:
connecting.mdlocal-settings.mdsafety-perimeter.mdoutput-formats.mdschema-introspection.mdexplain-reading.mdperf-and-processes.md
Security
- The skill refuses to put passwords on the command line.
-p<password>leaks viaps; the plugin uses login-paths,~/.my.cnf, or--defaults-fileexclusively. - The skill runs a "where am I" probe before any query and surfaces the answer (
@@hostname,@@read_only,USER(), …) so you can spot a misrouted connection before it does damage. - The skill sets
--safe-updates/sql_safe_updateson every session. Even if you somehow bypassed the read-only stance, accidental WHERE-lessUPDATE/DELETEis server-rejected. - The subagent has no
Edit,WriteorAgenttools, but it does haveBash, so its refusal to write is instruction-level. Use a read-only database user for real enforcement. - When
.claude/mysql-client.local.mdis in play,connection_cmd's output (a URL) is piped through the bundled converter into a mode-600 file at a unique temporary path in a private per-user directory, and never enters the conversation transcript. The file is deleted at the end of every turn; an interrupted turn can leave its file behind; remove only that retained path, taking care not to delete credentials used by another chat.
Troubleshooting
- Connection trouble, or first-time setup. Run
/mysql-client:doctor— it checks the client install, the settings file, thatconnection_cmdresolves, and that a probe actually connects, printing a fix for each failure. - The skill didn't fire when I expected. Re-phrase the request to include a concrete MySQL trigger phrase (
mysql,EXPLAIN,SELECT, schema name). The skill's description prioritises specificity over breadth. - The skill fired on something I wanted handled in plain Bash. Tell Claude to skip the skill for this turn ("just run the literal command I wrote, don't engage the mysql-client skill").
mysql_config_editor: command not found. You're on a MariaDB-only system (MariaDB ships no equivalent). Use~/.my.cnfwithchmod 600instead.Access denied for user '...'@'<host>'. Wrong host part of the grant. Have someone who can run it executeSHOW GRANTS FOR '<user>'@'%'(or whichever pattern was set up).
License
AGPL-3.0-only. The whole claude-plugins repo is AGPL for consistency. See LICENSE.