MySQL Read-Only Query Skill
Execute safe, read-only queries against configured MySQL databases.
Requirements
- Python 3.8+
- mysql-connector-python:
pip install -r requirements.txt
Setup
Create connections.json in the skill directory or ~/.config/claude/mysql-connections.json.
Security: Set file permissions to 600 since it contains credentials:
chmod 600 connections.json
{
"databases": [
{
"name": "production",
"description": "Main app database - users, orders, transactions",
"host": "db.example.com",
"port": 3306,
"database": "app_prod",
"user": "readonly_user",
"password": "your-password",
"ssl_disabled": false
}
]
}
Config Fields
| Field |
Required |
Description |
| name |
Yes |
Identifier for the database (case-insensitive) |
| description |
Yes |
What data this database contains (used for auto-selection) |
| host |
Yes |
Database hostname |
| port |
No |
Port number (default: 3306) |
| database |
Yes |
Database name |
| user |
Yes |
Username |
| password |
Yes |
Password |
| ssl_disabled |
No |
Set to true to disable SSL (default: false) |
| ssl_ca |
No |
Path to CA certificate file |
| ssl_cert |
No |
Path to client certificate file |
| ssl_key |
No |
Path to client private key file |
Usage
List configured databases
python3 scripts/query.py --list
Query a database
python3 scripts/query.py --db production --query "SELECT * FROM users LIMIT 10"
List tables
python3 scripts/query.py --db production --tables
Show schema
python3 scripts/query.py --db production --schema
Limit results
python3 scripts/query.py --db production --query "SELECT * FROM orders" --limit 100
Database Selection
Match user intent to database description:
| User asks about |
Look for description containing |
| users, accounts |
users, accounts, customers |
| orders, sales |
orders, transactions, sales |
| analytics, metrics |
analytics, metrics, reports |
| logs, events |
logs, events, audit |
If unclear, run --list and ask user which database.
Safety Features
- Read-only session: Connection uses MySQL
SET SESSION TRANSACTION READ ONLY (primary protection)
- Query validation: Only SELECT, SHOW, DESCRIBE, EXPLAIN, WITH queries allowed
- Single statement: Multiple statements per query rejected
- SSL support: Configurable SSL with CA, client cert, and key support
- Query timeout: 30-second max_execution_time enforced (MySQL 5.7.8+)
- Memory protection: Max 10,000 rows per query to prevent OOM
- Column width cap: 100 char max per column for readable output
- Credential sanitization: Error messages don't leak passwords
Troubleshooting
| Error |
Solution |
| Config not found |
Create connections.json in skill directory |
| Authentication failed |
Check username/password in config |
| Connection timeout |
Verify host/port, check firewall/VPN |
| SSL error |
Try "ssl_disabled": true for local databases |
| Permission warning |
Run chmod 600 connections.json |
| max_execution_time not supported |
Upgrade to MySQL 5.7.8+ or MariaDB 10.1.1+ |
Exit Codes
- 0: Success
- 1: Error (config missing, auth failed, invalid query, database error)
Workflow
- Run
--list to show available databases
- Match user intent to database description
- Run
--tables or --schema to explore structure
- Execute query with appropriate LIMIT
1---2name: mysql3description: Execute read-only SQL queries against multiple MySQL databases. Use when: (1) querying MySQL databases, (2) exploring database schemas/tables, (3) running SELECT queries for data analysis, (4) checking database contents. Supports multiple database connections with descriptions for intelligent auto-selection. Blocks all write operations (INSERT, UPDATE, DELETE, DROP, etc.) for safety.4license: Apache-2.05---6# MySQL Read-Only Query Skill78Execute safe, read-only queries against configured MySQL databases.910## Requirements1112- Python 3.8+13- mysql-connector-python: `pip install -r requirements.txt`1415## Setup1617Create `connections.json` in the skill directory or `~/.config/claude/mysql-connections.json`.1819**Security**: Set file permissions to `600` since it contains credentials:20```bash21chmod 600 connections.json22```2324```json25{26 "databases": [27 {28 "name": "production",29 "description": "Main app database - users, orders, transactions",30 "host": "db.example.com",31 "port": 3306,32 "database": "app_prod",33 "user": "readonly_user",34 "password": "your-password",35 "ssl_disabled": false36 }37 ]38}39```4041### Config Fields4243| Field | Required | Description |44|-------|----------|-------------|45| name | Yes | Identifier for the database (case-insensitive) |46| description | Yes | What data this database contains (used for auto-selection) |47| host | Yes | Database hostname |48| port | No | Port number (default: 3306) |49| database | Yes | Database name |50| user | Yes | Username |51| password | Yes | Password |52| ssl_disabled | No | Set to `true` to disable SSL (default: false) |53| ssl_ca | No | Path to CA certificate file |54| ssl_cert | No | Path to client certificate file |55| ssl_key | No | Path to client private key file |5657## Usage5859### List configured databases60```bash61python3 scripts/query.py --list62```6364### Query a database65```bash66python3 scripts/query.py --db production --query "SELECT * FROM users LIMIT 10"67```6869### List tables70```bash71python3 scripts/query.py --db production --tables72```7374### Show schema75```bash76python3 scripts/query.py --db production --schema77```7879### Limit results80```bash81python3 scripts/query.py --db production --query "SELECT * FROM orders" --limit 10082```8384## Database Selection8586Match user intent to database `description`:8788| User asks about | Look for description containing |89|-----------------|--------------------------------|90| users, accounts | users, accounts, customers |91| orders, sales | orders, transactions, sales |92| analytics, metrics | analytics, metrics, reports |93| logs, events | logs, events, audit |9495If unclear, run `--list` and ask user which database.9697## Safety Features9899- **Read-only session**: Connection uses MySQL `SET SESSION TRANSACTION READ ONLY` (primary protection)100- **Query validation**: Only SELECT, SHOW, DESCRIBE, EXPLAIN, WITH queries allowed101- **Single statement**: Multiple statements per query rejected102- **SSL support**: Configurable SSL with CA, client cert, and key support103- **Query timeout**: 30-second max_execution_time enforced (MySQL 5.7.8+)104- **Memory protection**: Max 10,000 rows per query to prevent OOM105- **Column width cap**: 100 char max per column for readable output106- **Credential sanitization**: Error messages don't leak passwords107108## Troubleshooting109110| Error | Solution |111|-------|----------|112| Config not found | Create `connections.json` in skill directory |113| Authentication failed | Check username/password in config |114| Connection timeout | Verify host/port, check firewall/VPN |115| SSL error | Try `"ssl_disabled": true` for local databases |116| Permission warning | Run `chmod 600 connections.json` |117| max_execution_time not supported | Upgrade to MySQL 5.7.8+ or MariaDB 10.1.1+ |118119## Exit Codes120121- **0**: Success122- **1**: Error (config missing, auth failed, invalid query, database error)123124## Workflow1251261. Run `--list` to show available databases1272. Match user intent to database description1283. Run `--tables` or `--schema` to explore structure1294. Execute query with appropriate LIMIT