db-mysql
GitHub用于查询、探索或审计 MySQL/MariaDB 数据库的技能。支持通过标签或索引选择连接,默认只读,提供健康检查、Schema 浏览及结构化 JSON 输出,适用于数据验证与业务分析场景。
Trigger Scenarios
Install
npx skills add evolution-foundation/evo-nexus --skill db-mysql -g -y
SKILL.md
Frontmatter
{
"name": "db-mysql",
"metadata": {
"openclaw": {
"files": [
"scripts\/*",
"references\/*"
],
"requires": {
"env": [
"DB_MYSQL_1_LABEL"
],
"bins": [
"python3"
]
},
"primaryEnv": "DB_MYSQL_1_LABEL"
}
},
"description": "Query MySQL \/ MariaDB databases configured in .env (DB_MYSQL_N_*). Use when the user asks to query, explore, or audit data in a MySQL database. Picks connection by label (e.g. 'orders-dev', 'analytics-prod') or numeric index. Read-only by default — writes refused unless DB_MYSQL_N_ALLOW_WRITE=true on that block."
}
db-mysql
Query MySQL / MariaDB databases declared in .env. Connections follow the same numbered pattern as SOCIAL_YOUTUBE_N_* / SOCIAL_INSTAGRAM_N_* — one block per database, labelled for humans, picked by label or index at call time.
Setup — one-time, per database
Add a block to .env (gitignored). Increment the index per connection:
# ── MySQL: orders-dev ────────────────────────────────
DB_MYSQL_1_LABEL=orders-dev
DB_MYSQL_1_HOST=mysql.dev.internal
DB_MYSQL_1_PORT=3306
DB_MYSQL_1_DATABASE=orders
DB_MYSQL_1_USER=agent_readonly
DB_MYSQL_1_PASSWORD=... # raw; .env is gitignored
# DB_MYSQL_1_SSL_CA_PATH=/path/ca.pem # optional, enables TLS verification
# DB_MYSQL_1_ALLOW_WRITE=false # default false
# DB_MYSQL_1_QUERY_TIMEOUT=30 # seconds, default 30
# DB_MYSQL_1_MAX_ROWS=1000 # default 1000
Alternative — full DSN instead of components (DSN wins when both are set):
DB_MYSQL_2_LABEL=analytics-prod
DB_MYSQL_2_DSN=mysql://agent_ro:***@analytics.prod.internal:3306/analytics
LABEL is always required — it's how agents pick the connection.
Usage
All commands output a single JSON line on stdout (safe to pipe). Errors go to stderr as JSON and exit non-zero.
List configured connections
python3 .claude/skills/db-mysql/scripts/db_client.py accounts
Health-check a connection
python3 .claude/skills/db-mysql/scripts/db_client.py test orders-dev
Run a read-only query
python3 .claude/skills/db-mysql/scripts/db_client.py query orders-dev \
"SELECT count(*) FROM customers WHERE created_at > now() - interval 7 day"
Explore schema
# List all tables (excludes mysql/information_schema/performance_schema/sys)
python3 .claude/skills/db-mysql/scripts/db_client.py tables orders-dev
# Describe a table
python3 .claude/skills/db-mysql/scripts/db_client.py describe orders-dev customers
# Schema-qualified:
python3 .claude/skills/db-mysql/scripts/db_client.py describe orders-dev analytics.events
Output shape
Successful query:
{
"ok": true,
"query_id": "uuid-v4",
"label": "orders-dev",
"columns": ["id", "email", "created_at"],
"rows": [[1, "a@b.com", "2026-04-22 12:00:00"]],
"row_count": 1,
"truncated": false,
"full_result_path": null,
"execution_time_ms": 12
}
When rows exceed MAX_ROWS, truncated is true and full_result_path points to a CSV in ADWs/logs/db-queries/<query_id>.csv — the agent can read that file directly instead of re-running.
Error:
{"ok": false, "error_code": "write_blocked", "error": "Write query blocked — connection 'orders-dev' has ALLOW_WRITE=false. ...", "label": "orders-dev"}
Error codes:
no_connections— noDB_MYSQL_N_*blocks in.envnot_found— label/index doesn't match any blockambiguous— multiple blocks share the same label (use index instead)config_error— block present but required field missing (typicallyLABEL)driver_missing—pymysqlnot installedconnection_failed— network, auth, TLS, orMAX_EXECUTION_TIMEtrippedwrite_blocked— write verb detected withoutALLOW_WRITE=truemulti_statement— more than one statement in a single callusage— wrong CLI args
Guardrails
- Write verbs (
DELETE | UPDATE | INSERT | REPLACE | TRUNCATE | DROP | ALTER | CREATE | GRANT | REVOKE | RENAME | LOAD | CALL | HANDLER) — refused unlessDB_MYSQL_N_ALLOW_WRITE=true. - Multi-statement queries — refused in v1. Supports
--,#, and/* */comment styles. - Query timeout — sets
SESSION MAX_EXECUTION_TIME = <QUERY_TIMEOUT>son the session (MySQL 5.7.4+; MariaDB honorsmax_statement_timebut the SET statement is ignored gracefully on older versions). - Result size —
fetchmany(MAX_ROWS + 1)to detect truncation; full result streamed to CSV when truncated so the agent context never holds >1000 rows. utf8mb4charset enforced on the connection to avoid mojibake on modern collations.
Workflow
- If the user doesn't specify a label, run
accountsto see what's configured and pick the one that matches their intent. If ambiguous, ask. - Write the smallest SQL that answers the question — prefer aggregates,
LIMIT, andEXPLAINbefore dumping rows. - Run via
query. Inspect the result. - For performance-sensitive queries, load the deep-dive references below.
Dependencies
- Python 3.10+
pymysql— not pre-installed;uv pip install pymysqlon first use. Pure-Python driver, no system libs required.
Deep-dive references
These load the PlanetScale database-skills repo verbatim — same content the upstream authors ship for their own tooling.
- EXPLAIN analysis
- Composite indexes
- Covering indexes
- Fulltext indexes
- Index maintenance
- Primary keys
- Data types
- Character sets
- Isolation levels
- Deadlocks
- Row locking gotchas
- Online DDL
- Partitioning
- Replication lag
- Connection management
- N+1 queries
- Query optimization pitfalls
- JSON column patterns
Upstream: planetscale/database-skills (MIT). Credit to PlanetScale for the reference content.
Version History
- 7f5dd76 Current 2026-07-25 04:53


