Install any skill in seconds. Free to start, no credit card required.
Get Started Free →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.
.claude/skills/evolution-foundation-db-mysql/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-08 | ✗→✓ | ▲ Improved | 225% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 43% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 28% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 13% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 265% | 0% |
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.
Add a block to .env (gitignored). Increment the index per connection:
env# ── 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):
envDB_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.
All commands output a single JSON line on stdout (safe to pipe). Errors go to stderr as JSON and exit non-zero.
bashpython3 .claude/skills/db-mysql/scripts/db_client.py accounts
bashpython3 .claude/skills/db-mysql/scripts/db_client.py test orders-dev
bashpython3 .claude/skills/db-mysql/scripts/db_client.py query orders-dev \ "SELECT count(*) FROM customers WHERE created_at > now() - interval 7 day"
bash# 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
Successful query:
json{ "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:
json{"ok": false, "error_code": "write_blocked", "error": "Write query blocked — connection 'orders-dev' has ALLOW_WRITE=false. ...", "label": "orders-dev"}
Error codes:
no_connections — no DB_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 (typically LABEL)driver_missing — pymysql not installedconnection_failed — network, auth, TLS, or MAX_EXECUTION_TIME trippedwrite_blocked — write verb detected without ALLOW_WRITE=truemulti_statement — more than one statement in a single callusage — wrong CLI argsDELETE | UPDATE | INSERT | REPLACE | TRUNCATE | DROP | ALTER | CREATE | GRANT | REVOKE | RENAME | LOAD | CALL | HANDLER) — refused unless DB_MYSQL_N_ALLOW_WRITE=true.--, #, and /* */ comment styles.SESSION MAX_EXECUTION_TIME = <QUERY_TIMEOUT>s on the session (MySQL 5.7.4+; MariaDB honors max_statement_time but the SET statement is ignored gracefully on older versions).fetchmany(MAX_ROWS + 1) to detect truncation; full result streamed to CSV when truncated so the agent context never holds >1000 rows.utf8mb4 charset enforced on the connection to avoid mojibake on modern collations.accounts to see what's configured and pick the one that matches their intent. If ambiguous, ask.LIMIT, and EXPLAIN before dumping rows.query. Inspect the result.pymysql — not pre-installed; uv pip install pymysql on first use. Pure-Python driver, no system libs required.These load the PlanetScale database-skills repo verbatim — same content the upstream authors ship for their own tooling.
Upstream: planetscale/database-skills (MIT). Credit to PlanetScale for the reference content.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 16,578 | 6,089 | -63% | 1 | 1 | 0% | 1,381 | 2,339 | +69% | 0 | 0 | — |
case-02 | fail→fail | 5,584 | 4,450 | -20% | 1 | 1 | 0% | 970 | 2,407 | +148% | 0 | 0 | — |
case-03 | fail→fail | 6,399 | 4,752 | -26% | 1 | 1 | 0% | 1,116 | 2,295 | +106% | 0 | 0 | — |
case-04 | pass→pass | 13,509 | 9,827 | -27% | 1 | 1 | 0% | 2,446 | 4,069 | +66% | 0 | 0 | — |
case-05 | pass→pass | 20,653 | 18,102 | -12% | 1 | 1 | 0% | 3,954 | 5,603 | +42% | 0 | 0 | — |
case-06 | pass→pass | 3,912 | 3,600 | -8% | 1 | 1 | 0% | 679 | 2,751 | +305% | 0 | 0 | — |
case-07 | pass→pass | 10,119 | 1,825 | -82% | 1 | 1 | 0% | 1,650 | 2,435 | +48% | 0 | 0 | — |
case-08 | fail→pass | 4,181 | 1,995 | -52% | 1 | 1 | 0% | 774 | 2,513 | +225% | 0 | 0 | — |
case-09 | fail→pass | 11,251 | 2,672 | -76% | 1 | 1 | 0% | 1,823 | 2,603 | +43% | 0 | 0 | — |
case-10 | fail→pass | 11,956 | 2,786 | -77% | 1 | 1 | 0% | 2,027 | 2,585 | +28% | 0 | 0 | — |
case-11 | fail→pass | 13,618 | 2,233 | -84% | 1 | 1 | 0% | 2,252 | 2,543 | +13% | 0 | 0 | — |
case-12 | fail→pass | 3,763 | 1,743 | -54% | 1 | 1 | 0% | 656 | 2,396 | +265% | 0 | 0 | — |
case-13 | pass→pass | 14,608 | 3,651 | -75% | 1 | 1 | 0% | 2,460 | 2,716 | +10% | 0 | 0 | — |
case-14 | pass→pass | 13,532 | 6,874 | -49% | 1 | 1 | 0% | 2,494 | 2,782 | +12% | 0 | 0 | — |
case-15 | fail→pass | 6,064 | 2,397 | -60% | 1 | 1 | 0% | 1,038 | 2,528 | +144% | 0 | 0 | — |
case-16 | pass→pass | 11,808 | 2,013 | -83% | 1 | 1 | 0% | 1,962 | 2,453 | +25% | 0 | 0 | — |
case-17 | pass→pass | 9,214 | 2,285 | -75% | 1 | 1 | 0% | 1,611 | 2,520 | +56% | 0 | 0 | — |
case-18 | pass→pass | 6,833 | 1,830 | -73% | 1 | 1 | 0% | 1,177 | 2,422 | +106% | 0 | 0 | — |
case-19 | fail→pass | 9,274 | 1,539 | -83% | 1 | 1 | 0% | 1,575 | 2,350 | +49% | 0 | 0 | — |
case-20 | fail→pass | 14,694 | 1,877 | -87% | 1 | 1 | 0% | 2,477 | 2,376 | -4% | 0 | 0 | — |
case-21 | fail→pass | 3,588 | 1,695 | -53% | 1 | 1 | 0% | 524 | 2,387 | +356% | 0 | 0 | — |
case-22 | fail→pass | 11,226 | 1,687 | -85% | 1 | 1 | 0% | 1,801 | 2,387 | +33% | 0 | 0 | — |
case-23 | fail→pass | 9,390 | 4,700 | -50% | 1 | 1 | 0% | 1,509 | 3,034 | +101% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted, and 20 counted toward the lift figure. The other 3 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +48 percentage points is the difference between those two pass rates over the 20 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.