{"id":"b1fb0a62-b470-40ce-a18f-6b901429f116","entityType":"agent","slug":"clawhub-zw008-mysql-aiops","name":"mysql-aiops","canonicalUrl":"https://www.xpersona.co/agent/clawhub-zw008-mysql-aiops","canonicalPath":"/agent/clawhub-zw008-mysql-aiops","generatedAt":"2026-10-10T15:52:51.575Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:26:20.307Z","emptyReason":null},"description":"Use this skill whenever the user needs to operate or troubleshoot a MySQL 8.x or MariaDB 10.6+ server as a DBA — a one-shot server health overview (version + flavor, connection headroom, replica role); server reads (global variables, status counters, databases, storage engines); activity (sessions/processlist, long-running queries, open InnoDB transactions, lock waits); query stats (performance_schema statement-digest top-N, EXPLAIN FORMAT=JSON); index health (unused indexes, redundant/duplicate indexes, cardinality); table health (sizes, data_free fragmentation, engine/row-format status); replication (replica IO/SQL thread state and lag, binlog/GTID status); four flagship analyses — slow-query RCA (worst digest + EXPLAIN → cited cause/action incl. full-scan and lock-time-dominant classification), InnoDB lock-wait & deadlock chain RCA (wait-for tree, root blocker, last deadlock parsed from SHOW ENGINE INNODB STATUS), replication lag RCA (thread state/error fields → cause+action), and table fragmentation analysis (data_free → OPTIMIZE candidates); and guarded writes (kill a session or query, OPTIMIZE/ANALYZE TABLE, create/drop an index, SET GLOBAL a variable, reset digest stats). Always use this skill for \"mysql health check\", \"why is this query slow\", \"top queries by time\", \"EXPLAIN this\", \"table fragmentation\", \"which indexes are unused\", \"redundant index\", \"who is blocking whom\", \"deadlock\", \"kill the session holding the lock\", \"replication lag\", \"replica stopped\", \"seconds behind master/source\", \"OPTIMIZE this table\", \"create/drop an index\", or \"SET GLOBAL max_connections\" when the context is a MySQL or MariaDB database. Do NOT use for PostgreSQL — use postgres-aiops. Do NOT use when the target is OT / industrial equipment (use industrial-aiops), a hypervisor, a storage appliance, a backup product, or a container/cluster orchestrator (negative routing hints only). Common MySQL/MariaDB DBA operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Behaviour is validated by a mock-based test suite; see docs/VERIFICATION.md for the live-verification checklist.","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.4K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s171xgnmqse0nqvgqvqnaq5f9183kyre:mysql-aiops","sourceUrl":"https://clawhub.ai/zw008/mysql-aiops","homepage":"https://clawhub.ai/zw008/skills/mysql-aiops","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/zw008/mysql-aiops","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/zw008/skills/mysql-aiops","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":63,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"mysql-aiops technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:26:20.307Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:26:20.307Z","emptyReason":null},"stars":null,"forks":null,"downloads":1412,"packageName":null,"latestVersion":"0.10.4","tractionLabel":"1.4K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:26:20.306Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T13:26:20.307Z","lastCrawledAt":"2026-10-10T13:26:20.306Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T13:26:20.306Z","lastVerifiedAt":null,"highlights":[{"version":"0.10.4","createdAt":"2026-09-16T23:26:08.267Z","changelog":"## mysql-aiops 0.10.4 - Documentation update: revised `references/agent-guardrails.md`. - Removed `skill-card.md` documentation file. - No changes to core functionality or CLI interface.","fileCount":7,"zipByteSize":20450},{"version":"0.10.3","createdAt":"2026-09-15T06:07:44.325Z","changelog":"- Removed the sample file skill-card.md. - No functional or behavioral changes to the mysql-aiops skill itself.","fileCount":7,"zipByteSize":20195},{"version":"0.10.2","createdAt":"2026-09-12T14:31:21.670Z","changelog":"- Removed skill-card.md from the project. - SKILL.md updated; no end-user functional or feature changes described in this version.","fileCount":7,"zipByteSize":19847},{"version":"0.10.1","createdAt":"2026-09-12T10:15:08.164Z","changelog":"- Removed the skill-card.md file. - SKILL.md content updated; no functional or tool changes indicated. - No new features or breaking changes. - Documentation and metadata refresh only.","fileCount":7,"zipByteSize":19907},{"version":"0.10.0","createdAt":"2026-09-12T01:03:49.665Z","changelog":"mysql-aiops 0.10.0 - Expanded binary support: the skill can now work if either `mysql-aiops` or `uvx` is available. - Metadata updated to require `anyBins` (either `mysql-aiops` or `uvx`), improving compatibility with different environments. - Environment configuration options clarified and more flexible in metadata. - Removed the standalone skill-card.md file.","fileCount":7,"zipByteSize":19894},{"version":"0.9.0","createdAt":"2026-08-13T00:27:38.644Z","changelog":"- Removed the file: skill-card.md - No functional or behavioral changes to the skill itself; documentation file cleanup only.","fileCount":7,"zipByteSize":19970},{"version":"0.8.0","createdAt":"2026-08-10T06:52:26.804Z","changelog":"- Removed the file: skill-card.md. - No changes to core features or functionality.","fileCount":7,"zipByteSize":19897},{"version":"0.7.0","createdAt":"2026-08-10T03:58:32.862Z","changelog":"- Removed the skill-card.md file. - No user-facing features or functionality were changed in this version.","fileCount":7,"zipByteSize":19927}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s171xgnmqse0nqvgqvqnaq5f9183kyre:mysql-aiops","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s171xgnmqse0nqvgqvqnaq5f9183kyre:mysql-aiops` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/zw008/mysql-aiops before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-mysql-aiops/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-mysql-aiops/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-mysql-aiops/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-zw008-mysql-aiops/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-zw008-mysql-aiops/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-zw008-mysql-aiops/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T15:52:51.571Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-mysql-aiops/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-mysql-aiops/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-mysql-aiops/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-mysql-aiops/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:26:20.307Z","emptyReason":null},"readme":"Skill: mysql-aiops\n\nOwner: zw008\n\nSummary: Use this skill whenever the user needs to operate or troubleshoot a MySQL 8.x or MariaDB 10.6+ server as a DBA — a one-shot server health overview (version + flavor, connection headroom, replica role); server reads (global variables, status counters, databases, storage engines); activity (sessions/processlist, long-running queries, open InnoDB transactions, lock waits); query stats (performance_schema statement-digest top-N, EXPLAIN FORMAT=JSON); index health (unused indexes, redundant/duplicate indexes, cardinality); table health (sizes, data_free fragmentation, engine/row-format status); replication (replica IO/SQL thread state and lag, binlog/GTID status); four flagship analyses — slow-query RCA (worst digest + EXPLAIN → cited cause/action incl. full-scan and lock-time-dominant classification), InnoDB lock-wait & deadlock chain RCA (wait-for tree, root blocker, last deadlock parsed from SHOW ENGINE INNODB STATUS), replication lag RCA (thread state/error fields → cause+action), and table fragmentation analysis (data_free → OPTIMIZE candidates); and guarded writes (kill a session or query, OPTIMIZE/ANALYZE TABLE, create/drop an index, SET GLOBAL a variable, reset digest stats). Always use this skill for \"mysql health check\", \"why is this query slow\", \"top queries by time\", \"EXPLAIN this\", \"table fragmentation\", \"which indexes are unused\", \"redundant index\", \"who is blocking whom\", \"deadlock\", \"kill the session holding the lock\", \"replication lag\", \"replica stopped\", \"seconds behind master/source\", \"OPTIMIZE this table\", \"create/drop an index\", or \"SET GLOBAL max_connections\" when the context is a MySQL or MariaDB database. Do NOT use for PostgreSQL — use postgres-aiops. Do NOT use when the target is OT / industrial equipment (use industrial-aiops), a hypervisor, a storage appliance, a backup product, or a container/cluster orchestrator (negative routing hints only). Common MySQL/MariaDB DBA operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Behaviour is validated by a mock-based test suite; see docs/VERIFICATION.md for the live-verification checklist.\n\nTags: latest:0.10.4\n\nVersion history:\n\nv0.10.4 | 2026-09-16T23:26:08.267Z | auto\n\n## mysql-aiops 0.10.4\n\n- Documentation update: revised `references/agent-guardrails.md`.\n- Removed `skill-card.md` documentation file.\n- No changes to core functionality or CLI interface.\n\nv0.10.3 | 2026-09-15T06:07:44.325Z | auto\n\n- Removed the sample file skill-card.md.\n- No functional or behavioral changes to the mysql-aiops skill itself.\n\nv0.10.2 | 2026-09-12T14:31:21.670Z | auto\n\n- Removed skill-card.md from the project.\n- SKILL.md updated; no end-user functional or feature changes described in this version.\n\nv0.10.1 | 2026-09-12T10:15:08.164Z | auto\n\n- Removed the skill-card.md file.\n- SKILL.md content updated; no functional or tool changes indicated.\n- No new features or breaking changes.\n- Documentation and metadata refresh only.\n\nv0.10.0 | 2026-09-12T01:03:49.665Z | auto\n\nmysql-aiops 0.10.0\n\n- Expanded binary support: the skill can now work if either `mysql-aiops` or `uvx` is available.\n- Metadata updated to require `anyBins` (either `mysql-aiops` or `uvx`), improving compatibility with different environments.\n- Environment configuration options clarified and more flexible in metadata.\n- Removed the standalone skill-card.md file.\n\nv0.9.0 | 2026-08-13T00:27:38.644Z | auto\n\n- Removed the file: skill-card.md\n- No functional or behavioral changes to the skill itself; documentation file cleanup only.\n\nv0.8.0 | 2026-08-10T06:52:26.804Z | auto\n\n- Removed the file: skill-card.md.\n- No changes to core features or functionality.\n\nv0.7.0 | 2026-08-10T03:58:32.862Z | auto\n\n- Removed the skill-card.md file.\n- No user-facing features or functionality were changed in this version.\n\nv0.6.0 | 2026-08-03T05:53:43.895Z | auto\n\n- Removed the file: skill-card.md\n- No user-facing features or code changes; only documentation cleanup.\n\nv0.5.0 | 2026-08-02T09:40:27.825Z | auto\n\n## mysql-aiops 0.5.0\n\n- Removed the file: `skill-card.md`\n- No other functional or documentation changes detected in this version.\n\nv0.4.0 | 2026-07-21T09:41:55.995Z | auto\n\nmysql-aiops 0.4.0\n\n- Updated governance documentation to clarify the audit, budget, undo, and risk-tier mechanisms.\n- Revised references/agent-guardrails.md and references/setup-guide.md for clearer onboarding and security guidance.\n- Adjusted SKILL.md to reflect clarified governance harness behavior (specifically, marking @governed_tool as a recorder, not authorizer).\n- Removed obsolete skill-card.md file.\n\nv0.3.0 | 2026-07-20T11:16:12.593Z | auto\n\nmysql-aiops 0.3.0\n\n- Removed the sample file skill-card.md.\n- No functional or compatibility changes; documentation only.\n\nv0.2.2 | 2026-07-19T17:35:58.174Z | auto\n\n## mysql-aiops 0.2.2\n\n- Removed the file `skill-card.md` from the repository.\n- No functional or interface changes to the skill itself.\n- Documentation and metadata remain unchanged, aside from file removal.\n\nv0.2.1 | 2026-07-19T13:11:15.665Z | auto\n\nmysql-aiops 0.2.1\n\n- Removed the file skill-card.md from the repository.\n- No code or functional changes introduced.\n- Housekeeping update to maintain repository cleanliness.\n\nv0.2.0 | 2026-07-19T03:52:13.686Z | auto\n\nmysql-aiops 0.2.0\n\n- Added agent guardrails documentation (references/agent-guardrails.md).\n- Introduced two new undo tools, expanding the toolset from 33 to 35.\n- Updated documentation to clarify test coverage: mock-based validation is now emphasized, with live-verification checklist available.\n- Improved CLI references and setup guide for clearer onboarding and usage.\n- Removed obsolete skill-card.md file.\n\nv0.1.0 | 2026-07-17T05:57:12.718Z | auto\n\nmysql-aiops 0.1.0 – Initial Preview Release\n\n- Introduces a standalone MySQL/MariaDB DBA toolkit with built-in governance (audit log, policy, undo, risk-tiers).\n- Secure password management: stores MySQL account passwords encrypted (Fernet/scrypt), never plaintext.\n- Covers 33 read/write DBA operations: health check, slow query & lock RCA, index/table analysis, session/replica management, and more.\n- All writes are audited, reversible where possible, and require confirmation and dry-run support.\n- No external dependencies; applies only to MySQL 8.x/MariaDB 10.6+ in preview/mock validation mode.\n- Not for use with PostgreSQL, non-database, or appliance/cluster/OT targets.\n\nArchive index:\n\nArchive v0.10.4: 7 files, 20450 bytes\n\nFiles: references/agent-guardrails.md (7466b), references/capabilities.md (6001b), references/cli-reference.md (3976b), references/setup-guide.md (4324b), skill-card.md (2728b), SKILL.md (19002b), _meta.json (131b)\n\nFile v0.10.4:SKILL.md\n\n---\nname: mysql-aiops\nslug: mysql-aiops\ndisplayName: \"MySQL AIops\"\nsummary: \"Governed MySQL/MariaDB DBA ops: slow-query, lock-wait, replication & fragmentation RCA; 35 tools.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/MySQL-AIops\ntags: [aiops, mcp, governance, mysql]\ndescription: >\n  Use this skill whenever the user needs to operate or troubleshoot a MySQL 8.x or MariaDB 10.6+ server as a DBA — a one-shot server health overview (version + flavor, connection headroom, replica role); server reads (global variables, status counters, databases, storage engines); activity (sessions/processlist, long-running queries, open InnoDB transactions, lock waits); query stats (performance_schema statement-digest top-N, EXPLAIN FORMAT=JSON); index health (unused indexes, redundant/duplicate indexes, cardinality); table health (sizes, data_free fragmentation, engine/row-format status); replication (replica IO/SQL thread state and lag, binlog/GTID status); four flagship analyses — slow-query RCA (worst digest + EXPLAIN → cited cause/action incl. full-scan and lock-time-dominant classification), InnoDB lock-wait & deadlock chain RCA (wait-for tree, root blocker, last deadlock parsed from SHOW ENGINE INNODB STATUS), replication lag RCA (thread state/error fields → cause+action), and table fragmentation analysis (data_free → OPTIMIZE candidates); and guarded writes (kill a session or query, OPTIMIZE/ANALYZE TABLE, create/drop an index, SET GLOBAL a variable, reset digest stats).\n  Always use this skill for \"mysql health check\", \"why is this query slow\", \"top queries by time\", \"EXPLAIN this\", \"table fragmentation\", \"which indexes are unused\", \"redundant index\", \"who is blocking whom\", \"deadlock\", \"kill the session holding the lock\", \"replication lag\", \"replica stopped\", \"seconds behind master/source\", \"OPTIMIZE this table\", \"create/drop an index\", or \"SET GLOBAL max_connections\" when the context is a MySQL or MariaDB database.\n  Do NOT use for PostgreSQL — use postgres-aiops. Do NOT use when the target is OT / industrial equipment (use industrial-aiops), a hypervisor, a storage appliance, a backup product, or a container/cluster orchestrator (negative routing hints only).\n  Common MySQL/MariaDB DBA operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Behaviour is validated by a mock-based test suite; see docs/VERIFICATION.md for the live-verification checklist.\ninstaller:\n  kind: uv\n  package: mysql-aiops\nargument-hint: \"[session id / table / index name or describe your DBA task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"mysql-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"MYSQL_AIOPS_CONFIG\",\"MYSQL_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/MySQL-AIops\",\"emoji\":\"🐬\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed MySQL/MariaDB DBA operations. The governance harness (audit, policy, token/runaway budget, undo, risk-tiers) is bundled in the package — no external skill-family dependency. Connects via PyMySQL (30s timeouts) and reads information_schema / performance_schema; the server flavor (mysql vs mariadb) is detected from version() and flavor-dependent statements branch (SHOW REPLICA STATUS vs SHOW SLAVE STATUS; performance_schema.data_lock_waits vs information_schema.innodb_lock_waits).\n  All write operations are audited to a local SQLite DB under ~/.mysql-aiops/ (relocatable via MYSQL_AIOPS_HOME).\n  Credentials: the MySQL account password is stored ENCRYPTED in ~/.mysql-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'mysql-aiops init' to onboard, or 'mysql-aiops secret set <target>' to add one. The store is unlocked by a master password from MYSQL_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var MYSQL_<TARGET_NAME_UPPER>_PASSWORD is still honoured as a fallback with a deprecation warning (migrate with 'mysql-aiops secret migrate'). The password is passed to pymysql.connect at connect time and held only in memory; it is never logged or echoed.\n  SQL safety: all values are bound query parameters; the few identifiers that cannot be parameterised (schema/table/index/column/variable names, ORDER BY columns) are validated against a strict identifier charset / allow-lists and backtick-quoted before interpolation. EXPLAIN rejects multi-statement input; the drop_index undo replay path is shape-gated to CREATE [UNIQUE] INDEX statements.\n  State-changing operations require double confirmation at the CLI layer and support --dry-run. All write tools pass through the @governed_tool decorator (budget/runaway guard + audit + risk-tier label — it records, not authorizes) and take a dry_run preview. Reversible writes fetch the real before-state first and record a faithful inverse (create_index↔drop_index, where drop rebuilds the definition from SHOW CREATE TABLE; set_global_variable restores the prior value); irreversible ops (kill session/query, optimize/analyze, reset stats) record prior state only.\n  Webhooks: none — no outbound network calls beyond the configured MySQL connection.\n  TLS: ssl_mode follows MySQL client semantics (default preferred); set verify_ca/verify_identity (with ssl_ca) on untrusted networks.\n  Transitive dependencies: PyMySQL (pure-Python MySQL driver) and the MCP SDK. No post-install scripts or background services.\n  VERIFICATION: the information_schema / performance_schema queries are modelled from documented MySQL 8.x / MariaDB 10.6+ shapes and are validated by a mock-based test suite; they have not yet been exercised against a live server (see docs/VERIFICATION.md). Community-maintained; not affiliated with Oracle or the MariaDB Foundation — trademarks belong to their owners.\n---\n\n# MySQL AIops\n\n> **Disclaimer**: Community-maintained open-source project, **not affiliated with, endorsed by, or sponsored by Oracle Corporation or the MariaDB Foundation.** \"MySQL\" and \"MariaDB\" trademarks belong to their owners. Source at [github.com/AIops-tools/MySQL-AIops](https://github.com/AIops-tools/MySQL-AIops) under the MIT license.\n\nGoverned MySQL / MariaDB DBA operations — **35 MCP tools**, every one wrapped with the bundled `@governed_tool` harness: a local unified audit log under `~/.mysql-aiops/`, token/runaway budget guard, undo-token recording, and descriptive risk-tier labels. The account password is stored **encrypted** (`~/.mysql-aiops/secrets.enc`, Fernet + scrypt) — never plaintext on disk.\n\n> **Standalone**: the governance harness is bundled in the package (`mysql_aiops.governance`) — mysql-aiops has no external skill-family dependency. Behaviour is covered by a mock-based test suite; `docs/VERIFICATION.md` is the checklist for a live run against a real MySQL / MariaDB server.\n\n## What This Skill Does\n\n| Domain | Tools | Count | Read or Write |\n|--------|-------|:-----:|:-------------:|\n| **Overview** | server health snapshot (version+flavor, connections, replica role) | 1 | 1 read |\n| **Server** | version+flavor, variables, status, databases, engines, connection stats | 6 | 6 read |\n| **Activity** | sessions, long-running queries, transactions, lock waits | 4 | 4 read |\n| **Queries** | top-N statement digests, EXPLAIN FORMAT=JSON | 2 | 2 read |\n| **Indexes** | unused, redundant/duplicate, cardinality stats | 3 | 3 read |\n| **Tables** | sizes, data_free fragmentation, engine/row-format status | 3 | 3 read |\n| **Replication** | replica status/lag, binlog/GTID | 2 | 2 read |\n| **Analysis (flagship)** | slow-query RCA, lock-wait & deadlock RCA, replication-lag RCA, fragmentation | 4 | 4 read |\n| **Writes** | kill-session, kill-query, drop-index | 3 | 3 write (high) |\n| | optimize, analyze-table, create-index, SET GLOBAL, reset-stats | 5 | 5 write (medium) |\n| **Undo** | undo list, undo apply | 2 | 1 read / 1 write |\n\nThe flagship analyses accept injected records for pure/offline analysis, or pull live from a configured target. `top_queries` / `slow_query_rca` require `performance_schema=ON`; the read account should have `PROCESS`, `REPLICATION CLIENT` and `SELECT` on `performance_schema`.\n\n## Quick Install\n\n```bash\nuv tool install mysql-aiops\nmysql-aiops init       # interactive wizard: connection + encrypted password\nmysql-aiops doctor     # connectivity + flavor + performance_schema + replica role\n```\n\nOr as an OpenClaw plugin, which installs this skill and its MCP server together:\n\n```bash\nopenclaw plugins install clawhub:@zw008/mysql-aiops\nopenclaw skills info mysql-aiops          # expect: Visible to model: yes\n```\n\nNeeds `uvx` on `PATH`: the MCP server is fetched with uv, pinned to this release.\n\n## When to Use This Skill\n\n- Triage a server (`overview`): version + flavor, uptime, connection headroom, sessions by command, longest query, most fragmented table, replica role\n- Root-cause a slow query (`analyze slow-query` / `slow_query_rca`): the worst statement digest + EXPLAIN → cited cause and action (full scan, lock-time dominant, tmp-disk spill, N+1)\n- Untangle a lock pile-up or deadlock (`analyze lock-waits` / `lock_wait_rca`): the wait-for tree with the root blocker named + the last deadlock parsed from `SHOW ENGINE INNODB STATUS`\n- Diagnose replication (`analyze replication` / `replication_lag_rca`): IO/SQL thread state, `Seconds_Behind_Source`, error fields → cause + action\n- Decide what to OPTIMIZE (`analyze fragmentation` / `fragmentation_analysis`): tables ranked by reclaimable `data_free`\n- Find unused / redundant indexes; check table sizes and engines; inspect binlog/GTID state\n- Kill a session or its query, OPTIMIZE/ANALYZE a table, create/drop an index (reversible), or SET GLOBAL a variable — all with dry-run + double-confirm\n\n**Do NOT use for PostgreSQL — use postgres-aiops.** Do NOT use when the target is OT/industrial equipment (use industrial-aiops), a hypervisor, a storage appliance, a backup product, or a container cluster.\n\n## Related Skills — Skill Routing\n\n| If the user wants… | Use |\n|--------------------|-----|\n| MySQL / MariaDB DBA-ops: slow queries, lock waits, replication, fragmentation | **mysql-aiops** (this skill) |\n| PostgreSQL DBA-ops | **postgres-aiops** |\n| OT / industrial edge (Modbus, OPC-UA, PLC, PROFINET) | the **industrial-aiops** line |\n| Hypervisor VM lifecycle (power, snapshot, migrate) | a hypervisor ops skill |\n| Container/cluster lifecycle | a cluster ops skill |\n\n## Common Workflows\n\n### 1. \"The application is slow\" — from complaint to a working index\n\n1. `mysql-aiops doctor` → connectivity, detected flavor, and whether\n   `performance_schema` is actually enabled (if it is off, the digest-based analysis\n   below has nothing to read — fix that first).\n2. `mysql-aiops overview` → one-shot: version, connection counts, buffer-pool and\n   activity headline, so you know whether this is a query problem or a load problem.\n3. `mysql-aiops analyze slow-query` → the worst statement digests, each with cited\n   findings (full scan / no index used, lock time dominant, rows examined per row sent,\n   tmp-table spill to disk, high call count) and a concrete action per finding.\n4. `mysql-aiops query top --limit 20` → confirm the digest the RCA blamed really is the\n   top consumer, not a one-off.\n5. `mysql-aiops query explain \"<sql>\"` → read the actual plan. `access_type: ALL` on a\n   large table is the signature that an index will help; a plan already using an index\n   means the fix is elsewhere.\n6. `mysql-aiops index unused` and `mysql-aiops index redundant` → before adding one,\n   check you are not duplicating an index that already exists (a redundant index costs\n   writes and buys nothing).\n7. `mysql-aiops remediate create-index <table> <col> --name idx_x --dry-run` → prints\n   the exact DDL; re-run without `--dry-run` (double-confirm). The write is reversible\n   and records an inverse `drop_index` undo descriptor.\n8. Re-run `mysql-aiops query explain \"<sql>\"` and `analyze slow-query` to prove the plan\n   changed and the digest dropped.\n9. **Failure branch**: if the plan did not change, the optimizer may be working from\n   stale statistics — `mysql-aiops remediate analyze-table <table>` and re-check. If the\n   index made things *worse* (write amplification, or the optimizer picking it wrongly),\n   reverse it: `mysql-aiops undo list` → `mysql-aiops undo apply <id>` drops exactly the\n   index that was created. Index DDL on a large table can be long-running — if it stalls,\n   `mysql-aiops activity long --min-seconds 60` will show it, and cancelling mid-DDL is\n   its own risk, so size the table with `mysql-aiops table sizes` *before* step 7.\n\n### 2. A lock pile-up is stalling writes\n\n1. `mysql-aiops activity lock-waits` → the raw blocking/blocked pairs, straight from\n   the server.\n2. `mysql-aiops analyze lock-waits` → the wait-for tree resolved down to the **root\n   blocker** session, with the last deadlock (victim + both statements) attached.\n3. `mysql-aiops activity transactions` → what the root blocker is actually doing and how\n   long it has been open. An idle-in-transaction blocker is an application bug, not a\n   database one.\n4. `mysql-aiops activity sessions --no-sleeping` → confirm the blocker's user, host, and\n   statement before you touch it.\n5. Cancel the statement, not the connection, if that is enough:\n   `mysql-aiops remediate kill-query <session-id> --dry-run` then for real\n   (double-confirm). Escalate to `mysql-aiops remediate kill <session-id>` only if the\n   session must go.\n6. Re-run `mysql-aiops analyze lock-waits` → the tree should be empty.\n7. **Failure branch**: `kill` and `kill-query` are **irreversible — they record no\n   undo**, and killing a long-running transaction triggers a rollback that can itself\n   take a long time and hold locks meanwhile. If the tree does not clear, do not kill\n   more sessions in a loop (the runaway budget guard will stop you anyway): re-read\n   `activity transactions` to see whether the rollback is in progress, and go after the\n   application holding the transaction open instead.\n\n### 3. A replica has fallen behind\n\n1. `mysql-aiops analyze replication` → the cited cause: IO thread stopped (with the real\n   `Last_IO_Error`), SQL thread stopped (with `Last_SQL_Error`), applier simply lagging,\n   or an intentional `SQL_Delay`.\n2. `mysql-aiops repl status` → the raw replica record, so you can see the seconds-behind\n   value and thread states the analysis quoted. Note the tool branches on flavor\n   automatically (`SHOW REPLICA STATUS` on MySQL, `SHOW SLAVE STATUS` on MariaDB).\n3. `mysql-aiops repl binlog` → binlog position and retention, to judge whether the\n   replica can still catch up or has fallen off the end of the logs.\n4. `mysql-aiops overview` on the replica → check the lag is not just resource pressure\n   masquerading as a replication fault.\n5. Apply the cause-specific fix: connectivity/credentials for a stopped IO thread, the\n   diverged row for a stopped SQL thread, or parallel apply for a slow applier —\n   `mysql-aiops remediate set slave_parallel_workers 4 --dry-run` first (reversible; the\n   prior value is captured as the undo descriptor).\n6. **Failure branch**: an intentional `SQL_Delay` is *not* a fault — the analysis says so,\n   and \"fixing\" it defeats a deliberate safety window. If a `SET GLOBAL` made things\n   worse, `mysql-aiops undo apply <id>` restores the **prior** value. If the replica has\n   fallen off the retained binlogs, no setting will recover it — it needs a reseed, which\n   is out of this tool's scope.\n\n### 4. Reclaim space from a bloated table\n\n1. `mysql-aiops analyze fragmentation` → tables ranked by reclaimable `data_free`, each\n   citing the measured bytes.\n2. `mysql-aiops table sizes` and `mysql-aiops table fragmentation` → confirm the size and\n   free space independently, and see how big the rebuild will actually be.\n3. `mysql-aiops index unused` → while you are here, an index nothing has used is dead\n   weight; `mysql-aiops index stats` shows the usage numbers behind that claim.\n4. `mysql-aiops remediate drop-index <table> <index-name> --dry-run` then for real — the\n   write rebuilds the index definition from `SHOW CREATE TABLE` **before** dropping, so\n   the undo descriptor recreates exactly the index that existed.\n5. `mysql-aiops remediate optimize <table> --dry-run` → preview, then re-run to\n   `OPTIMIZE TABLE` (double-confirm).\n6. Re-run `mysql-aiops analyze fragmentation` to confirm the space came back.\n7. **Failure branch**: `OPTIMIZE TABLE` rebuilds the table and can lock or block writes\n   for the duration on a large table — run it in a maintenance window, and check\n   `mysql-aiops activity long` if the system goes quiet. It records **no** undo (there is\n   nothing to reverse). If dropping the index turned out to be wrong,\n   `mysql-aiops undo apply <id>` recreates it from the captured definition — this is the\n   one step in this recipe that *is* reversible, which is why it comes before the\n   OPTIMIZE.\n\n### Offline analysis (no live server)\n\nPass data straight to the analysis tools — `slow_query_rca(statements=[...])`, `lock_wait_rca(pairs=[...])`, `replication_lag_rca(status={...})`, or `fragmentation_analysis(tables=[...])` — to analyse an exported dataset without connecting.\n\n## Governance & Safety\n\nThe skill delivers reads and writes and records them; it does **not** decide whether a write is\npermitted. That is your agent's judgement, or the permission of the account you connect it with\n(point it at a MySQL/MariaDB account granted only SELECT / PROCESS / REPLICATION CLIENT and no\nwrite privileges (no INSERT/UPDATE/DELETE/DDL) — writes then fail at the server). There is no\nread-only switch, policy file, or approval gate.\n\n- **Audit is the guarantee, and it is not bypassable.** Every operation — MCP and CLI alike — is logged to `~/.mysql-aiops/audit.db` (relocatable via `MYSQL_AIOPS_HOME`): params, result, status, duration, and the risk tier. The CLI writes the same row the MCP path does.\n- `MYSQL_AUDIT_APPROVED_BY` / `MYSQL_AUDIT_RATIONALE` are optional annotations recorded on the audit row (who/why); they are never required and never block.\n- **Runaway guard** — a safety backstop, not authorization: the same call looped in a tight window trips a circuit breaker. Disable with `MYSQL_RUNAWAY_MAX=0`.\n- Writes support `--dry-run` / `dry_run=True` and double confirmation at the CLI.\n- Reversible writes fetch the real before-state and record an inverse descriptor; irreversible ops (kill session/query, optimize/analyze, reset stats) record prior state only.\n- All values are bound query parameters; identifiers that cannot be parameterised are validated and backtick-quoted.\n\n## References\n\n- `references/capabilities.md` — full tool + field reference\n- `references/cli-reference.md` — CLI command reference\n- `references/setup-guide.md` — onboarding, credentials, and connectivity\n\nFile v0.10.4:_meta.json\n\n{\n  \"ownerId\": \"kn7b067awq2s97bn3d7p5qfhw5827pxc\",\n  \"slug\": \"mysql-aiops\",\n  \"version\": \"0.10.4\",\n  \"publishedAt\": 1789601168267\n}\n\nFile v0.10.4:references/agent-guardrails.md\n\n# Agent guardrails — running mysql-aiops with a smaller / local model\n\nIf you drive these tools with a local model (Llama, Qwen, Mistral … via Goose,\nOllama, LM Studio, or any OpenAI-compatible runtime), you will get noticeably\nbetter results with a short system prompt. This page gives you one, and — more\nimportantly — tells you which guardrails you **no longer need to write**, because\nthe tool now enforces them itself.\n\nThe distinction matters. A guardrail in a prompt is a request. A guardrail in the\nharness is a guarantee. Anything below that we could move into the harness, we did.\n\n## What the tool now enforces — do not waste prompt budget on these\n\nAuthorization is not this tool's job — decide it via the account you connect with or the\nagent's prompt, not via a switch this skill provides. See below for the account-side way to\nget a read-only setup.\n\n| You might be tempted to prompt | Why you don't need to |\n|---|---|\n| \"Never write SQL that modifies data\" | The tool exposes no arbitrary-SQL surface at all. Every statement is built from a fixed template; identifiers are validated against a strict charset and backtick-quoted, and values are always bound as query parameters. `explain_query` runs `EXPLAIN`, not your statement. |\n| \"Don't invent a value when a field is missing\" | A NULL column comes back as `null`, never as `\"\"`. A sleeping session's `query` is `null` (it is running nothing), not blank; MariaDB's absent `gtid_mode` is `null`, not `\"\"`. |\n| \"Tell me if the output was cut off\" | `top_queries`, `table_sizes`, `table_fragmentation` and `table_status` return `{\"statements\"/\"tables\": [...], \"returned\": N, \"limit\": L, \"truncated\": true/false}`. Truncation is measured — one extra row is requested — not guessed from a length coincidence. |\n| \"Make it show the number it judged on\" | Every finding cites the values that tripped it — `noIndexUsedPct`, `rowsExaminedPerSent`, `lockTimePct`, `tmpDiskTables` and `calls` for a statement (the `worst` block additionally reports `meanTimeMs` and `totalTimeMs`, which no check is tripped by); `ioThreadRunning`, `sqlThreadRunning` and `secondsBehindSource` for a replica — so a claim can be checked against a figure rather than taken on the model's word. `lock_wait_rca` returns no findings at all: it gives you `roots` ordered by `blockedCount` plus `worstRootId`, which names the blocker outright. |\n| \"Confirm before anything destructive\" | `drop_index`, `kill_query`/`kill_session` and `optimize_table` require a `--dry-run`-able preview plus double confirmation at the CLI. `drop_index` captures the index's `SHOW CREATE` definition first, so the undo token can recreate it exactly. |\n| \"Log what you did\" | Every governed call is audited to `~/.mysql-aiops/audit.db` regardless of what the model says it did. |\n\n## What still needs a prompt\n\nThese are model-behaviour problems the harness cannot fix from the outside.\n\n⚠️ **Do not read priority off list position — except from `lock_wait_rca`.** `slow_query_rca`\nand `replication_lag_rca` append their `findings` in the order the checks run; the sort inside\n`slow_query_rca` orders the *statements* it picks `worst` from, not the findings. Neither\nfinding carries a `rank` or a `severity`, so nothing in those two payloads says which finding\nmatters most. (`lock_wait_rca` is the exception — its `roots` are ordered by `blockedCount`\nand `worstRootId` names the worst one.)\n\nCopy this into your agent's system prompt:\n\n```text\nYou operate a MySQL or MariaDB server through the mysql-aiops MCP tools.\n\nTOOL USE\n- Before answering any question about the current database, you MUST call a\n  tool. Never answer from memory or assumption.\n- Actually invoke the tool. Do not describe the call you would make, and do not\n  emit an example JSON response in place of calling it.\n- If a tool call fails, report the real error verbatim. Never fill the gap with\n  a plausible-sounding answer.\n\nREADING RESULTS\n- Read the whole result before concluding. If a result contains a \"truncated\"\n  field that is true, say so and re-run with a higher limit. The slowest query\n  on the server may be the one just past the cut-off.\n- Findings from `slow_query_rca` and `replication_lag_rca` are NOT ordered by severity and\n  carry no rank. Weigh each finding's own numbers and say which one you acted on; never\n  treat the first as the headline.\n- A null field means the server returned NULL or had no such value. Report it\n  as \"not available\" — never infer it. A session with a null \"query\" is idle,\n  not running an unknown statement.\n- Report values exactly as returned. Times are already converted to\n  milliseconds; do not re-scale them. Do not prettify digests or table names.\n- Cite the measured number. \"mean_time 240ms over 15,000 calls\" is useful;\n  \"this query is slow\" is not.\n\nSCOPE\n- Separate observation from interpretation. State what the tools returned, then\n  any interpretation, clearly marked as such.\n- Do not recommend an index unless unused_indexes / redundant_indexes or an\n  EXPLAIN in the result supports it. Adding an index is not free.\n- Do not attribute replication lag to a cause the replication tools did not\n  measure. Check whether the IO and SQL threads are actually running first.\n- Do not confuse a thread id with a digest, a schema with a table, or\n  rows_examined with rows_sent — the gap between those last two is the point.\n- MySQL and MariaDB differ. The flavor is reported by server_version; do not\n  suggest a MySQL-only feature (like gtid_mode) on MariaDB.\n- performance_schema may be OFF, in which case top_queries returns nothing.\n  That is a configuration fact, not \"the server has no slow queries\".\n```\n\n## Recommended setup for a local model\n\nPoint the tool at a read-only database account until you trust the setup — that is where\nthe guarantee actually lives, not in a switch this skill provides:\n\n```bash\nmysql-aiops doctor\n```\n\nGrant the connecting account only `SELECT`, `PROCESS` and `REPLICATION CLIENT` (no\n`INSERT`/`UPDATE`/`DELETE`/DDL); any write tool the model calls will then fail at the server.\nWhen you are ready to allow writes, grant the account write privileges and, if you want a\nname on the audit trail, set an approver annotation (optional — it is recorded, never\nrequired):\n\n```bash\nexport MYSQL_AUDIT_APPROVED_BY=\"your.name@example.com\"\nexport MYSQL_AUDIT_RATIONALE=\"index cleanup, change ticket DB-4412\"\n```\n\n## If your model still struggles\n\nSome behaviours are model-capacity limits rather than prompt problems:\n\n- **Multi-tool workflows time out or drift.** Prefer the RCA tools —\n  `slow_query_rca` correlates digests, index usage and examined-row ratios\n  inside one call, so the model does not have to chain `top_queries`,\n  `explain_query` and `index_stats` and keep digests straight.\n- **The model ignores later tool results in a long context.** Statement digests\n  are the big payload here. Use `--limit` deliberately rather than pulling 200\n  digests when you want the top 10.\n- **The model describes calls instead of making them.** This is usually a\n  runtime/tool-calling-format mismatch, not a prompt problem — check that your\n  client advertises the tools in the format your model was trained on.\n\nFeedback on running this with a specific local model is genuinely useful —\nopen an issue at\n[github.com/AIops-tools/MySQL-AIops](https://github.com/AIops-tools/MySQL-AIops/issues)\nwith the model, runtime, and what went wrong.\n\nFile v0.10.4:references/capabilities.md\n\n# mysql-aiops capabilities\n\n> 35 MCP tools (26 read, 9 write); mock-validated, see `docs/VERIFICATION.md`. The\n> `information_schema` / `performance_schema` queries are modelled from\n> documented MySQL 8.x / MariaDB 10.6+ shapes and need live verification.\n> `top_queries` / `slow_query_rca` require `performance_schema=ON`; the read\n> account should have `PROCESS`, `REPLICATION CLIENT` and `SELECT` on\n> `performance_schema`.\n\n## Read tools (25)\n\n| Tool | Source | Returns |\n|------|--------|---------|\n| `overview` | several reads (resilient) | version, flavor, uptimeDays, readOnly, role, connections{}, sessionsByCommand, longestQuery, mostFragmentedTable, secondsBehindSource |\n| `server_version` | `version()`, `SHOW GLOBAL STATUS/VARIABLES` | version, flavor (mysql/mariadb), uptimeSeconds/Days, readOnly, superReadOnly, dataDirectory |\n| `show_variables` | `SHOW GLOBAL VARIABLES` | name, value (optional LIKE filter) |\n| `show_status` | `SHOW GLOBAL STATUS` | name, value (optional LIKE filter) |\n| `list_databases` | `information_schema.tables` | name, tableCount, data/index/totalBytes, totalPretty |\n| `list_engines` | `SHOW ENGINES` | engine, support, isDefault, transactions |\n| `connection_stats` | `SHOW GLOBAL STATUS/VARIABLES` | maxConnections, threadsConnected/Running, maxUsedConnections, abortedConnects, usedPct |\n| `list_sessions` | `information_schema.processlist` | total, byCommand, sleepingCount, sessions[] |\n| `long_running_queries` | processlist | thresholdSeconds, count, queries[] (oldest first) |\n| `list_transactions` | `information_schema.innodb_trx` | count, lockWaitCount, transactions[] (rowsLocked/Modified) |\n| `lock_waits` | `performance_schema.data_lock_waits` (MariaDB: `information_schema.innodb_lock_waits`) | pairs[] {blockedId, blockingId, waitSeconds, queries} |\n| `top_queries` | `events_statements_summary_by_digest` | statements[] (calls, total/mean ms, lockTimePct, noIndexUsedPct, rowsExaminedPerSent, tmpDiskTables) |\n| `explain_query` | `EXPLAIN FORMAT=JSON` | plan (JSON; planned, not executed) |\n| `unused_indexes` | `table_io_waits_summary_by_index_usage` | indexes[] with zero I/O since restart |\n| `redundant_indexes` | `information_schema.statistics` | redundant[] {index, coveredBy, exactDuplicate} |\n| `index_stats` | `information_schema.statistics` | indexes[] {columns, unique, cardinality} |\n| `table_sizes` | `information_schema.tables` | tables[] data/index/totalBytes, engine, estRows |\n| `table_fragmentation` | `information_schema.tables` | tables[] freeBytes (data_free), freePct |\n| `table_status` | `information_schema.tables` | tables[] engine, rowFormat, autoIncrement, updateTime; nonInnodbTables[] |\n| `replica_status` | `SHOW REPLICA STATUS` (MariaDB: `SHOW SLAVE STATUS`) | isReplica, replicas[] {ioThreadRunning, sqlThreadRunning, secondsBehindSource, lastIo/SqlError, gtid} |\n| `binlog_status` | `SHOW BINARY LOGS` + variables + processlist | logBin, serverId, binlogFormat, gtidMode, binlogCount/TotalBytes, downstreamReplicas[] |\n| `slow_query_rca` | digest rows + EXPLAIN | worst{}, planAccessTypes[], findings[] (cited cause/action) |\n| `lock_wait_rca` | lock-wait pairs + `SHOW ENGINE INNODB STATUS` | roots[], worstRootId, deadlockSuspected, lastDeadlock{victim, transactions} |\n| `replication_lag_rca` | replica status record | findings[] (IO/SQL thread stopped, lagging, intentional delay, healthy) |\n| `fragmentation_analysis` | fragmentation rows | recommendations[] (cited reasons + OPTIMIZE action) |\n\nThe flagship analyses accept injected records (`statements=` / `pairs=` /\n`status=` / `tables=`) for pure/offline analysis, or pull live from a\nconfigured `target`.\n\n## Write tools (8)\n\n| Tool | Risk | SQL | Undo / safety |\n|------|------|-----|---------------|\n| `kill_session` | **high** | `KILL CONNECTION <id>` | captures session user/host/query for audit; no safe inverse; dry-run + double-confirm |\n| `kill_query` | **high** | `KILL QUERY <id>` | captures session; session survives, statement aborted; no inverse; dry-run + double-confirm |\n| `drop_index` | **high** | `DROP INDEX ... ON ...` | rebuilds the definition from `SHOW CREATE TABLE` FIRST; undo = recreate exactly (replays via `create_index(definition=…)`); dry-run + double-confirm |\n| `optimize_table` | medium | `OPTIMIZE TABLE` | records prior size/data_free stats; no undo (rebuild) |\n| `analyze_table` | medium | `ANALYZE TABLE` | records prior stats; no undo |\n| `create_index` | medium | `CREATE [UNIQUE] INDEX` | returns created (table, name); undo = drop it |\n| `set_global_variable` | medium | `SET GLOBAL <name> = %s` | captures prior value from `SHOW GLOBAL VARIABLES`; undo = set back; runtime-only (persist yourself) |\n| `reset_query_stats` | medium | `TRUNCATE ...events_statements_summary_by_digest` | irreversible; no undo |\n\nAll values are bound query parameters; identifiers that cannot be parameterised\n(schema/table/index/column/variable names, ORDER BY columns) are validated\nagainst a strict identifier charset / allow-lists and backtick-quoted before\ninterpolation.\n\n## Flavor branching\n\n| Concern | MySQL 8.x | MariaDB 10.6+ |\n|---------|-----------|----------------|\n| Replica status | `SHOW REPLICA STATUS` (`Source_*`/`Replica_*` fields) | `SHOW SLAVE STATUS` (`Master_*`/`Slave_*` fields) |\n| Lock waits | `performance_schema.data_lock_waits` | `information_schema.innodb_lock_waits` |\n| Detection | `version()` without \"MariaDB\" | `version()` contains \"MariaDB\" |\n\nBoth result shapes are normalised into one record family; `doctor` and\n`overview` report the detected flavor.\n\n## Out of scope (by design)\n\n- Application-schema **migrations** / DDL beyond index maintenance\n- ORM / model management\n- Logical or physical **backup/restore** orchestration (mysqldump, PITR)\n- User/grant management and `CREATE`/`DROP DATABASE`\n- PostgreSQL (use **postgres-aiops**); OT / industrial equipment (use the\n  `industrial-aiops` line)\n\nWant one of these? Open an issue or PR — feedback and contributions welcome.\n\nFile v0.10.4:references/cli-reference.md\n\n# mysql-aiops CLI reference\n\n> The `information_schema` / `performance_schema` queries are modelled from documented\n> MySQL 8.x / MariaDB 10.6+ shapes and are mock-validated; see `docs/VERIFICATION.md`\n> for the live-run checklist.\n\n## Setup & diagnostics\n\n```bash\nmysql-aiops init                      # interactive onboarding wizard\nmysql-aiops doctor [--skip-auth]      # config + secrets + connectivity + flavor + perf-schema + replica role\nmysql-aiops overview [--target <t>]   # one-shot server health snapshot\nmysql-aiops mcp                       # start the MCP server (stdio transport)\n```\n\n## Secrets (encrypted store ~/.mysql-aiops/secrets.enc)\n\n```bash\nmysql-aiops secret set <target> [--value <pw>]    # store password (hidden prompt if no --value)\nmysql-aiops secret list                            # names only — values never shown\nmysql-aiops secret rm <target>\nmysql-aiops secret migrate                         # import legacy plaintext .env (MYSQL_<T>_PASSWORD)\nmysql-aiops secret rotate-password                 # re-encrypt under a new master password\n```\n\n## Read commands\n\n```bash\nmysql-aiops server version                 # version, flavor (mysql/mariadb), uptime, read_only\nmysql-aiops server variables [pattern]     # SHOW GLOBAL VARIABLES (optional name filter)\nmysql-aiops server status [pattern]        # SHOW GLOBAL STATUS (optional name filter)\nmysql-aiops server databases               # schemas + sizes\nmysql-aiops server engines                 # storage engines\nmysql-aiops server connections             # headroom vs max_connections\n\nmysql-aiops activity sessions [--no-sleeping]  # processlist + per-command counts\nmysql-aiops activity long [--min-seconds 60]\nmysql-aiops activity transactions          # open InnoDB transactions\nmysql-aiops activity lock-waits            # wait-for edges (flavor-branched)\n\nmysql-aiops query top [--order-by total_time] [--limit 20]   # statement digests\nmysql-aiops query explain \"<sql>\"          # EXPLAIN FORMAT=JSON (planned, not executed)\n\nmysql-aiops index unused                   # zero-I/O indexes since restart\nmysql-aiops index redundant                # prefix-covered / duplicate indexes\nmysql-aiops index stats                    # columns + cardinality\n\nmysql-aiops table sizes\nmysql-aiops table fragmentation            # data_free per table\nmysql-aiops table status                   # engine / row format / update time\n\nmysql-aiops repl status                    # replica threads + lag (flavor-branched)\nmysql-aiops repl binlog                    # binlog/GTID + downstream replicas\n\nmysql-aiops analyze slow-query [--explain \"<sql>\"]   # flagship RCA\nmysql-aiops analyze lock-waits             # chain + last deadlock\nmysql-aiops analyze replication            # lag/thread-state RCA\nmysql-aiops analyze fragmentation          # OPTIMIZE candidates\n```\n\n## Write commands (governed; risk tier in parentheses)\n\n```bash\nmysql-aiops remediate kill <id> [--dry-run]                    # (high) KILL CONNECTION; no undo; double confirm\nmysql-aiops remediate kill-query <id> [--dry-run]              # (high) KILL QUERY; no undo; double confirm\nmysql-aiops remediate drop-index <table> <name> [--dry-run]    # (high) reversible; double confirm\nmysql-aiops remediate optimize <table> [--dry-run]             # (medium) OPTIMIZE TABLE\nmysql-aiops remediate analyze-table <table> [--dry-run]        # (medium) ANALYZE TABLE\nmysql-aiops remediate create-index <table> <cols...> [--name N] [--unique] [--dry-run]  # (medium) reversible\nmysql-aiops remediate set <name> <value> [--dry-run]           # (medium) SET GLOBAL; reversible\nmysql-aiops query reset [--dry-run]                            # (medium) truncate digest stats\n```\n\n## Common options\n\n- `--target, -t <name>` — target name from `config.yaml` (omit to use the default/first target)\n- `--dry-run` — print the statement that would run, change nothing\n- State-changing commands require two confirmations at the CLI layer\n\nFile v0.10.4:references/setup-guide.md\n\n# mysql-aiops setup & security guide\n\n> Mock-validated; not yet run against a live MySQL / MariaDB server. `mysql-aiops doctor`\n> is the fastest live check — see `docs/VERIFICATION.md`.\n\n## 1. Install\n\n```bash\nuv tool install mysql-aiops\n```\n\n## 2. Prepare an account\n\nmysql-aiops connects with PyMySQL and reads `information_schema` /\n`performance_schema`. A least-privilege monitoring account works for the reads:\n\n```sql\nCREATE USER 'aiops'@'%' IDENTIFIED BY 'change-me';\nGRANT PROCESS, REPLICATION CLIENT ON *.* TO 'aiops'@'%';\nGRANT SELECT ON performance_schema.* TO 'aiops'@'%';\n-- performance_schema must be ON (default on MySQL 8.x) for query stats\n```\n\nMaintenance writes need more: `OPTIMIZE`/`ANALYZE`/`CREATE INDEX`/`DROP INDEX`\nrequire `ALTER` + `INDEX` (and `INSERT` for OPTIMIZE) on the target schema;\n`KILL` requires `CONNECTION_ADMIN` (or `SUPER`); `SET GLOBAL` requires\n`SYSTEM_VARIABLES_ADMIN` (or `SUPER`).\n\n## 3. Onboard\n\n```bash\nmysql-aiops init\n```\n\nThe wizard collects (non-secret) connection details into\n`~/.mysql-aiops/config.yaml` and stores the password **encrypted** into\n`~/.mysql-aiops/secrets.enc`. Example config:\n\n```yaml\ntargets:\n  - name: primary\n    host: 10.0.0.30\n    port: 3306\n    database: appdb\n    user: aiops\n    ssl_mode: verify_ca       # disabled/preferred/required/verify_ca/verify_identity\n    ssl_ca: /etc/ssl/mysql-ca.pem\n```\n\n## 4. Non-interactive use (MCP server / CI / cron)\n\nExport the master password so the encrypted store can be unlocked without a\nprompt:\n\n```bash\nexport MYSQL_AIOPS_MASTER_PASSWORD='your-master-password'\n```\n\n## Credential security\n\n- The password is **never** written to disk in plaintext. It lives only in\n  `~/.mysql-aiops/secrets.enc`, encrypted with Fernet (AES-128-CBC + HMAC),\n  the key derived from your master password via scrypt. Only a per-store random\n  salt and the ciphertext are on disk (chmod 600); the master password itself is\n  never stored.\n- A legacy plaintext env var `MYSQL_<TARGET_NAME_UPPER>_PASSWORD` is still\n  honoured as a fallback with a deprecation warning — migrate with\n  `mysql-aiops secret migrate` (it imports then renames the old `.env`).\n- The password is passed to `pymysql.connect` at connect time and held only in\n  memory; it is never logged or echoed. Exception text and tracebacks are\n  scrubbed of secret-shaped strings before being written to the audit log.\n\n## TLS\n\n`ssl_mode` follows MySQL client semantics and maps to PyMySQL TLS kwargs:\n\n| ssl_mode | Behaviour |\n|----------|-----------|\n| `disabled` | TLS off — isolated labs only |\n| `preferred` (default) | negotiate TLS when the server supports it |\n| `required` | force TLS, no certificate verification |\n| `verify_ca` | force TLS + verify the server cert against `ssl_ca` |\n| `verify_identity` | `verify_ca` + hostname check (recommended in production) |\n\n## SQL safety\n\n- All values (session ids, thresholds, limits, variable values) are **bound\n  query parameters** — never string-formatted into SQL.\n- The few identifiers that cannot be parameterised (schema/table/index/column\n  names, global variable names, `ORDER BY` columns) are validated against a\n  strict identifier charset / allow-lists and backtick-quoted before\n  interpolation; anything that is not a plain identifier is rejected.\n- `EXPLAIN` rejects multi-statement input (an embedded `;` is refused); the\n  `drop_index` undo replay is shape-gated to `CREATE [UNIQUE] INDEX` statements.\n\n## Governance harness state\n\nState lives under `~/.mysql-aiops/` (relocate with `MYSQL_AIOPS_HOME`):\n\n- `audit.db` — every tool call (SQLite), with risk tier and an optional approver/rationale\n  annotation (`MYSQL_AUDIT_APPROVED_BY` / `MYSQL_AUDIT_RATIONALE`) if you set one — never\n  required, never blocking\n- `undo.db` — inverse descriptors for reversible writes (e.g. `drop_index`)\n- budget / runaway guard — caps cumulative tool calls and wall-time; trips on\n  tight poll/retry loops\n\n## Verify\n\n```bash\nmysql-aiops doctor\n```\n\n`doctor` checks the config file, the encrypted store and its permissions, that a\npassword is present per target, and (unless `--skip-auth`) connectivity — then\nprobes `version()` (reporting the mysql/mariadb flavor), whether\n`performance_schema` is ON, and the replica role (`SHOW REPLICA STATUS`, or\n`SHOW SLAVE STATUS` on MariaDB).\n\nFile v0.10.4:skill-card.md\n\n## Description:\n\nProvides governed MySQL and MariaDB DBA operations for health checks, slow-query analysis, lock-wait and deadlock RCA, replication-lag diagnosis, fragmentation analysis, and guarded maintenance actions.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[zw008](https://clawhub.ai/user/zw008)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers, database administrators, and operations engineers use this skill to inspect and troubleshoot MySQL 8.x or MariaDB 10.6+ servers, produce RCA guidance, and run governed maintenance commands when intentionally authorized.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill exposes disruptive database write operations through MCP and does not enforce its own approval gate.\n\nMitigation: Use a least-privilege, preferably read-only MySQL or MariaDB account unless maintenance writes are intentionally authorized through external controls.\n\nRisk: Production use with broad database privileges can allow destructive actions such as killing sessions, dropping indexes, resetting query stats, or changing global variables.\n\nMitigation: Require explicit external approval, prefer dry-run previews, review audit records, and limit elevated grants to the target schemas and operations needed.\n\nRisk: Local state and non-interactive deployments depend on protected secrets and configuration under the mysql-aiops home directory.\n\nMitigation: Secure the local state directory, avoid weak placeholder passwords or wildcard host access, and protect MYSQL_AIOPS_MASTER_PASSWORD in CI or MCP deployments.\n\n## Reference(s):\n\n- [ClawHub Skill Page](https://clawhub.ai/zw008/skills/mysql-aiops)\n- [Project Homepage](https://github.com/AIops-tools/MySQL-AIops)\n- [Capabilities Reference](references/capabilities.md)\n- [CLI Reference](references/cli-reference.md)\n- [Setup and Security Guide](references/setup-guide.md)\n- [Agent Guardrails](references/agent-guardrails.md)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown and structured tool-call guidance with inline shell commands and configuration snippets]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May include cited RCA findings, SQL maintenance previews, dry-run instructions, and security guidance for database access.]\n\n## Skill Version(s):\n\n0.10.4 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v0.10.3: 7 files, 20195 bytes\n\nFiles: references/agent-guardrails.md (6367b), references/capabilities.md (6001b), references/cli-reference.md (3976b), references/setup-guide.md (4324b), skill-card.md (3375b), SKILL.md (19002b), _meta.json (131b)\n\nFile v0.10.3:SKILL.md\n\n---\nname: mysql-aiops\nslug: mysql-aiops\ndisplayName: \"MySQL AIops\"\nsummary: \"Governed MySQL/MariaDB DBA ops: slow-query, lock-wait, replication & fragmentation RCA; 35 tools.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/MySQL-AIops\ntags: [aiops, mcp, governance, mysql]\ndescription: >\n  Use this skill whenever the user needs to operate or troubleshoot a MySQL 8.x or MariaDB 10.6+ server as a DBA — a one-shot server health overview (version + flavor, connection headroom, replica role); server reads (global variables, status counters, databases, storage engines); activity (sessions/processlist, long-running queries, open InnoDB transactions, lock waits); query stats (performance_schema statement-digest top-N, EXPLAIN FORMAT=JSON); index health (unused indexes, redundant/duplicate indexes, cardinality); table health (sizes, data_free fragmentation, engine/row-format status); replication (replica IO/SQL thread state and lag, binlog/GTID status); four flagship analyses — slow-query RCA (worst digest + EXPLAIN → cited cause/action incl. full-scan and lock-time-dominant classification), InnoDB lock-wait & deadlock chain RCA (wait-for tree, root blocker, last deadlock parsed from SHOW ENGINE INNODB STATUS), replication lag RCA (thread state/error fields → cause+action), and table fragmentation analysis (data_free → OPTIMIZE candidates); and guarded writes (kill a session or query, OPTIMIZE/ANALYZE TABLE, create/drop an index, SET GLOBAL a variable, reset digest stats).\n  Always use this skill for \"mysql health check\", \"why is this query slow\", \"top queries by time\", \"EXPLAIN this\", \"table fragmentation\", \"which indexes are unused\", \"redundant index\", \"who is blocking whom\", \"deadlock\", \"kill the session holding the lock\", \"replication lag\", \"replica stopped\", \"seconds behind master/source\", \"OPTIMIZE this table\", \"create/drop an index\", or \"SET GLOBAL max_connections\" when the context is a MySQL or MariaDB database.\n  Do NOT use for PostgreSQL — use postgres-aiops. Do NOT use when the target is OT / industrial equipment (use industrial-aiops), a hypervisor, a storage appliance, a backup product, or a container/cluster orchestrator (negative routing hints only).\n  Common MySQL/MariaDB DBA operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Behaviour is validated by a mock-based test suite; see docs/VERIFICATION.md for the live-verification checklist.\ninstaller:\n  kind: uv\n  package: mysql-aiops\nargument-hint: \"[session id / table / index name or describe your DBA task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"mysql-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"MYSQL_AIOPS_CONFIG\",\"MYSQL_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/MySQL-AIops\",\"emoji\":\"🐬\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed MySQL/MariaDB DBA operations. The governance harness (audit, policy, token/runaway budget, undo, risk-tiers) is bundled in the package — no external skill-family dependency. Connects via PyMySQL (30s timeouts) and reads information_schema / performance_schema; the server flavor (mysql vs mariadb) is detected from version() and flavor-dependent statements branch (SHOW REPLICA STATUS vs SHOW SLAVE STATUS; performance_schema.data_lock_waits vs information_schema.innodb_lock_waits).\n  All write operations are audited to a local SQLite DB under ~/.mysql-aiops/ (relocatable via MYSQL_AIOPS_HOME).\n  Credentials: the MySQL account password is stored ENCRYPTED in ~/.mysql-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'mysql-aiops init' to onboard, or 'mysql-aiops secret set <target>' to add one. The store is unlocked by a master password from MYSQL_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var MYSQL_<TARGET_NAME_UPPER>_PASSWORD is still honoured as a fallback with a deprecation warning (migrate with 'mysql-aiops secret migrate'). The password is passed to pymysql.connect at connect time and held only in memory; it is never logged or echoed.\n  SQL safety: all values are bound query parameters; the few identifiers that cannot be parameterised (schema/table/index/column/variable names, ORDER BY columns) are validated against a strict identifier charset / allow-lists and backtick-quoted before interpolation. EXPLAIN rejects multi-statement input; the drop_index undo replay path is shape-gated to CREATE [UNIQUE] INDEX statements.\n  State-changing operations require double confirmation at the CLI layer and support --dry-run. All write tools pass through the @governed_tool decorator (budget/runaway guard + audit + risk-tier label — it records, not authorizes) and take a dry_run preview. Reversible writes fetch the real before-state first and record a faithful inverse (create_index↔drop_index, where drop rebuilds the definition from SHOW CREATE TABLE; set_global_variable restores the prior value); irreversible ops (kill session/query, optimize/analyze, reset stats) record prior state only.\n  Webhooks: none — no outbound network calls beyond the configured MySQL connection.\n  TLS: ssl_mode follows MySQL client semantics (default preferred); set verify_ca/verify_identity (with ssl_ca) on untrusted networks.\n  Transitive dependencies: PyMySQL (pure-Python MySQL driver) and the MCP SDK. No post-install scripts or background services.\n  VERIFICATION: the information_schema / performance_schema queries are modelled from documented MySQL 8.x / MariaDB 10.6+ shapes and are validated by a mock-based test suite; they have not yet been exercised against a live server (see docs/VERIFICATION.md). Community-maintained; not affiliated with Oracle or the MariaDB Foundation — trademarks belong to their owners.\n---\n\n# MySQL AIops\n\n> **Disclaimer**: Community-maintained open-source project, **not affiliated with, endorsed by, or sponsored by Oracle Corporation or the MariaDB Foundation.** \"MySQL\" and \"MariaDB\" trademarks belong to their owners. Source at [github.com/AIops-tools/MySQL-AIops](https://github.com/AIops-tools/MySQL-AIops) under the MIT license.\n\nGoverned MySQL / MariaDB DBA operations — **35 MCP tools**, every one wrapped with the bundled `@governed_tool` harness: a local unified audit log under `~/.mysql-aiops/`, token/runaway budget guard, undo-token recording, and descriptive risk-tier labels. The account password is stored **encrypted** (`~/.mysql-aiops/secrets.enc`, Fernet + scrypt) — never plaintext on disk.\n\n> **Standalone**: the governance harness is bundled in the package (`mysql_aiops.governance`) — mysql-aiops has no external skill-family dependency. Behaviour is covered by a mock-based test suite; `docs/VERIFICATION.md` is the checklist for a live run against a real MySQL / MariaDB server.\n\n## What This Skill Does\n\n| Domain | Tools | Count | Read or Write |\n|--------|-------|:-----:|:-------------:|\n| **Overview** | server health snapshot (version+flavor, connections, replica role) | 1 | 1 read |\n| **Server** | version+flavor, variables, status, databases, engines, connection stats | 6 | 6 read |\n| **Activity** | sessions, long-running queries, transactions, lock waits | 4 | 4 read |\n| **Queries** | top-N statement digests, EXPLAIN FORMAT=JSON | 2 | 2 read |\n| **Indexes** | unused, redundant/duplicate, cardinality stats | 3 | 3 read |\n| **Tables** | sizes, data_free fragmentation, engine/row-format status | 3 | 3 read |\n| **Replication** | replica status/lag, binlog/GTID | 2 | 2 read |\n| **Analysis (flagship)** | slow-query RCA, lock-wait & deadlock RCA, replication-lag RCA, fragmentation | 4 | 4 read |\n| **Writes** | kill-session, kill-query, drop-index | 3 | 3 write (high) |\n| | optimize, analyze-table, create-index, SET GLOBAL, reset-stats | 5 | 5 write (medium) |\n| **Undo** | undo list, undo apply | 2 | 1 read / 1 write |\n\nThe flagship analyses accept injected records for pure/offline analysis, or pull live from a configured target. `top_queries` / `slow_query_rca` require `performance_schema=ON`; the read account should have `PROCESS`, `REPLICATION CLIENT` and `SELECT` on `performance_schema`.\n\n## Quick Install\n\n```bash\nuv tool install mysql-aiops\nmysql-aiops init       # interactive wizard: connection + encrypted password\nmysql-aiops doctor     # connectivity + flavor + performance_schema + replica role\n```\n\nOr as an OpenClaw plugin, which installs this skill and its MCP server together:\n\n```bash\nopenclaw plugins install clawhub:@zw008/mysql-aiops\nopenclaw skills info mysql-aiops          # expect: Visible to model: yes\n```\n\nNeeds `uvx` on `PATH`: the MCP server is fetched with uv, pinned to this release.\n\n## When to Use This Skill\n\n- Triage a server (`overview`): version + flavor, uptime, connection headroom, sessions by command, longest query, most fragmented table, replica role\n- Root-cause a slow query (`analyze slow-query` / `slow_query_rca`): the worst statement digest + EXPLAIN → cited cause and action (full scan, lock-time dominant, tmp-disk spill, N+1)\n- Untangle a lock pile-up or deadlock (`analyze lock-waits` / `lock_wait_rca`): the wait-for tree with the root blocker named + the last deadlock parsed from `SHOW ENGINE INNODB STATUS`\n- Diagnose replication (`analyze replication` / `replication_lag_rca`): IO/SQL thread state, `Seconds_Behind_Source`, error fields → cause + action\n- Decide what to OPTIMIZE (`analyze fragmentation` / `fragmentation_analysis`): tables ranked by reclaimable `data_free`\n- Find unused / redundant indexes; check table sizes and engines; inspect binlog/GTID state\n- Kill a session or its query, OPTIMIZE/ANALYZE a table, create/drop an index (reversible), or SET GLOBAL a variable — all with dry-run + double-confirm\n\n**Do NOT use for PostgreSQL — use postgres-aiops.** Do NOT use when the target is OT/industrial equipment (use industrial-aiops), a hypervisor, a storage appliance, a backup product, or a container cluster.\n\n## Related Skills — Skill Routing\n\n| If the user wants… | Use |\n|--------------------|-----|\n| MySQL / MariaDB DBA-ops: slow queries, lock waits, replication, fragmentation | **mysql-aiops** (this skill) |\n| PostgreSQL DBA-ops | **postgres-aiops** |\n| OT / industrial edge (Modbus, OPC-UA, PLC, PROFINET) | the **industrial-aiops** line |\n| Hypervisor VM lifecycle (power, snapshot, migrate) | a hypervisor ops skill |\n| Container/cluster lifecycle | a cluster ops skill |\n\n## Common Workflows\n\n### 1. \"The application is slow\" — from complaint to a working index\n\n1. `mysql-aiops doctor` → connectivity, detected flavor, and whether\n   `performance_schema` is actually enabled (if it is off, the digest-based analysis\n   below has nothing to read — fix that first).\n2. `mysql-aiops overview` → one-shot: version, connection counts, buffer-pool and\n   activity headline, so you know whether this is a query problem or a load problem.\n3. `mysql-aiops analyze slow-query` → the worst statement digests, each with cited\n   findings (full scan / no index used, lock time dominant, rows examined per row sent,\n   tmp-table spill to disk, high call count) and a concrete action per finding.\n4. `mysql-aiops query top --limit 20` → confirm the digest the RCA blamed really is the\n   top consumer, not a one-off.\n5. `mysql-aiops query explain \"<sql>\"` → read the actual plan. `access_type: ALL` on a\n   large table is the signature that an index will help; a plan already using an index\n   means the fix is elsewhere.\n6. `mysql-aiops index unused` and `mysql-aiops index redundant` → before adding one,\n   check you are not duplicating an index that already exists (a redundant index costs\n   writes and buys nothing).\n7. `mysql-aiops remediate create-index <table> <col> --name idx_x --dry-run` → prints\n   the exact DDL; re-run without `--dry-run` (double-confirm). The write is reversible\n   and records an inverse `drop_index` undo descriptor.\n8. Re-run `mysql-aiops query explain \"<sql>\"` and `analyze slow-query` to prove the plan\n   changed and the digest dropped.\n9. **Failure branch**: if the plan did not change, the optimizer may be working from\n   stale statistics — `mysql-aiops remediate analyze-table <table>` and re-check. If the\n   index made things *worse* (write amplification, or the optimizer picking it wrongly),\n   reverse it: `mysql-aiops undo list` → `mysql-aiops undo apply <id>` drops exactly the\n   index that was created. Index DDL on a large table can be long-running — if it stalls,\n   `mysql-aiops activity long --min-seconds 60` will show it, and cancelling mid-DDL is\n   its own risk, so size the table with `mysql-aiops table sizes` *before* step 7.\n\n### 2. A lock pile-up is stalling writes\n\n1. `mysql-aiops activity lock-waits` → the raw blocking/blocked pairs, straight from\n   the server.\n2. `mysql-aiops analyze lock-waits` → the wait-for tree resolved down to the **root\n   blocker** session, with the last deadlock (victim + both statements) attached.\n3. `mysql-aiops activity transactions` → what the root blocker is actually doing and how\n   long it has been open. An idle-in-transaction blocker is an application bug, not a\n   database one.\n4. `mysql-aiops activity sessions --no-sleeping` → confirm the blocker's user, host, and\n   statement before you touch it.\n5. Cancel the statement, not the connection, if that is enough:\n   `mysql-aiops remediate kill-query <session-id> --dry-run` then for real\n   (double-confirm). Escalate to `mysql-aiops remediate kill <session-id>` only if the\n   session must go.\n6. Re-run `mysql-aiops analyze lock-waits` → the tree should be empty.\n7. **Failure branch**: `kill` and `kill-query` are **irreversible — they record no\n   undo**, and killing a long-running transaction triggers a rollback that can itself\n   take a long time and hold locks meanwhile. If the tree does not clear, do not kill\n   more sessions in a loop (the runaway budget guard will stop you anyway): re-read\n   `activity transactions` to see whether the rollback is in progress, and go after the\n   application holding the transaction open instead.\n\n### 3. A replica has fallen behind\n\n1. `mysql-aiops analyze replication` → the cited cause: IO thread stopped (with the real\n   `Last_IO_Error`), SQL thread stopped (with `Last_SQL_Error`), applier simply lagging,\n   or an intentional `SQL_Delay`.\n2. `mysql-aiops repl status` → the raw replica record, so you can see the seconds-behind\n   value and thread states the analysis quoted. Note the tool branches on flavor\n   automatically (`SHOW REPLICA STATUS` on MySQL, `SHOW SLAVE STATUS` on MariaDB).\n3. `mysql-aiops repl binlog` → binlog position and retention, to judge whether the\n   replica can still catch up or has fallen off the end of the logs.\n4. `mysql-aiops overview` on the replica → check the lag is not just resource pressure\n   masquerading as a replication fault.\n5. Apply the cause-specific fix: connectivity/credentials for a stopped IO thread, the\n   diverged row for a stopped SQL thread, or parallel apply for a slow applier —\n   `mysql-aiops remediate set slave_parallel_workers 4 --dry-run` first (reversible; the\n   prior value is captured as the undo descriptor).\n6. **Failure branch**: an intentional `SQL_Delay` is *not* a fault — the analysis says so,\n   and \"fixing\" it defeats a deliberate safety window. If a `SET GLOBAL` made things\n   worse, `mysql-aiops undo apply <id>` restores the **prior** value. If the replica has\n   fallen off the retained binlogs, no setting will recover it — it needs a reseed, which\n   is out of this tool's scope.\n\n### 4. Reclaim space from a bloated table\n\n1. `mysql-aiops analyze fragmentation` → tables ranked by reclaimable `data_free`, each\n   citing the measured bytes.\n2. `mysql-aiops table sizes` and `mysql-aiops table fragmentation` → confirm the size and\n   free space independently, and see how big the rebuild will actually be.\n3. `mysql-aiops index unused` → while you are here, an index nothing has used is dead\n   weight; `mysql-aiops index stats` shows the usage numbers behind that claim.\n4. `mysql-aiops remediate drop-index <table> <index-name> --dry-run` then for real — the\n   write rebuilds the index definition from `SHOW CREATE TABLE` **before** dropping, so\n   the undo descriptor recreates exactly the index that existed.\n5. `mysql-aiops remediate optimize <table> --dry-run` → preview, then re-run to\n   `OPTIMIZE TABLE` (double-confirm).\n6. Re-run `mysql-aiops analyze fragmentation` to confirm the space came back.\n7. **Failure branch**: `OPTIMIZE TABLE` rebuilds the table and can lock or block writes\n   for the duration on a large table — run it in a maintenance window, and check\n   `mysql-aiops activity long` if the system goes quiet. It records **no** undo (there is\n   nothing to reverse). If dropping the index turned out to be wrong,\n   `mysql-aiops undo apply <id>` recreates it from the captured definition — this is the\n   one step in this recipe that *is* reversible, which is why it comes before the\n   OPTIMIZE.\n\n### Offline analysis (no live server)\n\nPass data straight to the analysis tools — `slow_query_rca(statements=[...])`, `lock_wait_rca(pairs=[...])`, `replication_lag_rca(status={...})`, or `fragmentation_analysis(tables=[...])` — to analyse an exported dataset without connecting.\n\n## Governance & Safety\n\nThe skill delivers reads and writes and records them; it does **not** decide whether a write is\npermitted. That is your agent's judgement, or the permission of the account you connect it with\n(point it at a MySQL/MariaDB account granted only SELECT / PROCESS / REPLICATION CLIENT and no\nwrite privileges (no INSERT/UPDATE/DELETE/DDL) — writes then fail at the server). There is no\nread-only switch, policy file, or approval gate.\n\n- **Audit is the guarantee, and it is not bypassable.** Every operation — MCP and CLI alike — is logged to `~/.mysql-aiops/audit.db` (relocatable via `MYSQL_AIOPS_HOME`): params, result, status, duration, and the risk tier. The CLI writes the same row the MCP path does.\n- `MYSQL_AUDIT_APPROVED_BY` / `MYSQL_AUDIT_RATIONALE` are optional annotations recorded on the audit row (who/why); they are never required and never block.\n- **Runaway guard** — a safety backstop, not authorization: the same call looped in a tight window trips a circuit breaker. Disable with `MYSQL_RUNAWAY_MAX=0`.\n- Writes support `--dry-run` / `dry_run=True` and double confirmation at the CLI.\n- Reversible writes fetch the real before-state and record an inverse descriptor; irreversible ops (kill session/query, optimize/analyze, reset stats) record prior state only.\n- All values are bound query parameters; identifiers that cannot be parameterised are validated and backtick-quoted.\n\n## References\n\n- `references/capabilities.md` — full tool + field reference\n- `references/cli-reference.md` — CLI command reference\n- `references/setup-guide.md` — onboarding, credentials, and connectivity\n\nFile v0.10.3:_meta.json\n\n{\n  \"ownerId\": \"kn7b067awq2s97bn3d7p5qfhw5827pxc\",\n  \"slug\": \"mysql-aiops\",\n  \"version\": \"0.10.3\",\n  \"publishedAt\": 1789452464325\n}\n\nFile v0.10.3:references/agent-guardrails.md\n\n# Agent guardrails — running mysql-aiops with a smaller / local model\n\nIf you drive these tools with a local model (Llama, Qwen, Mistral … via Goose,\nOllama, LM Studio, or any OpenAI-compatible runtime), you will get noticeably\nbetter results with a short system prompt. This page gives you one, and — more\nimportantly — tells you which guardrails you **no longer need to write**, because\nthe tool now enforces them itself.\n\nThe distinction matters. A guardrail in a prompt is a request. A guardrail in the\nharness is a guarantee. Anything below that we could move into the harness, we did.\n\n## What the tool now enforces — do not waste prompt budget on these\n\nAuthorization is not this tool's job — decide it via the account you connect with or the\nagent's prompt, not via a switch this skill provides. See below for the account-side way to\nget a read-only setup.\n\n| You might be tempted to prompt | Why you don't need to |\n|---|---|\n| \"Never write SQL that modifies data\" | The tool exposes no arbitrary-SQL surface at all. Every statement is built from a fixed template; identifiers are validated against a strict charset and backtick-quoted, and values are always bound as query parameters. `explain_query` runs `EXPLAIN`, not your statement. |\n| \"Don't invent a value when a field is missing\" | A NULL column comes back as `null`, never as `\"\"`. A sleeping session's `query` is `null` (it is running nothing), not blank; MariaDB's absent `gtid_mode` is `null`, not `\"\"`. |\n| \"Tell me if the output was cut off\" | `top_queries`, `table_sizes`, `table_fragmentation` and `table_status` return `{\"statements\"/\"tables\": [...], \"returned\": N, \"limit\": L, \"truncated\": true/false}`. Truncation is measured — one extra row is requested — not guessed from a length coincidence. |\n| \"Preserve the ordering / tell me what's most urgent\" | `slow_query_rca`, `lock_wait_rca` and `replication_lag_rca` rank findings worst-first with the measured number attached. Priority is in the payload, not implied by list position. |\n| \"Confirm before anything destructive\" | `drop_index`, `kill_query`/`kill_session` and `optimize_table` require a `--dry-run`-able preview plus double confirmation at the CLI. `drop_index` captures the index's `SHOW CREATE` definition first, so the undo token can recreate it exactly. |\n| \"Log what you did\" | Every governed call is audited to `~/.mysql-aiops/audit.db` regardless of what the model says it did. |\n\n## What still needs a prompt\n\nThese are model-behaviour problems the harness cannot fix from the outside.\nCopy this into your agent's system prompt:\n\n```text\nYou operate a MySQL or MariaDB server through the mysql-aiops MCP tools.\n\nTOOL USE\n- Before answering any question about the current database, you MUST call a\n  tool. Never answer from memory or assumption.\n- Actually invoke the tool. Do not describe the call you would make, and do not\n  emit an example JSON response in place of calling it.\n- If a tool call fails, report the real error verbatim. Never fill the gap with\n  a plausible-sounding answer.\n\nREADING RESULTS\n- Read the whole result before concluding. If a result contains a \"truncated\"\n  field that is true, say so and re-run with a higher limit. The slowest query\n  on the server may be the one just past the cut-off.\n- A null field means the server returned NULL or had no such value. Report it\n  as \"not available\" — never infer it. A session with a null \"query\" is idle,\n  not running an unknown statement.\n- Report values exactly as returned. Times are already converted to\n  milliseconds; do not re-scale them. Do not prettify digests or table names.\n- Cite the measured number. \"mean_time 240ms over 15,000 calls\" is useful;\n  \"this query is slow\" is not.\n\nSCOPE\n- Separate observation from interpretation. State what the tools returned, then\n  any interpretation, clearly marked as such.\n- Do not recommend an index unless unused_indexes / redundant_indexes or an\n  EXPLAIN in the result supports it. Adding an index is not free.\n- Do not attribute replication lag to a cause the replication tools did not\n  measure. Check whether the IO and SQL threads are actually running first.\n- Do not confuse a thread id with a digest, a schema with a table, or\n  rows_examined with rows_sent — the gap between those last two is the point.\n- MySQL and MariaDB differ. The flavor is reported by server_version; do not\n  suggest a MySQL-only feature (like gtid_mode) on MariaDB.\n- performance_schema may be OFF, in which case top_queries returns nothing.\n  That is a configuration fact, not \"the server has no slow queries\".\n```\n\n## Recommended setup for a local model\n\nPoint the tool at a read-only database account until you trust the setup — that is where\nthe guarantee actually lives, not in a switch this skill provides:\n\n```bash\nmysql-aiops doctor\n```\n\nGrant the connecting account only `SELECT`, `PROCESS` and `REPLICATION CLIENT` (no\n`INSERT`/`UPDATE`/`DELETE`/DDL); any write tool the model calls will then fail at the server.\nWhen you are ready to allow writes, grant the account write privileges and, if you want a\nname on the audit trail, set an approver annotation (optional — it is recorded, never\nrequired):\n\n```bash\nexport MYSQL_AUDIT_APPROVED_BY=\"your.name@example.com\"\nexport MYSQL_AUDIT_RATIONALE=\"index cleanup, change ticket DB-4412\"\n```\n\n## If your model still struggles\n\nSome behaviours are model-capacity limits rather than prompt problems:\n\n- **Multi-tool workflows time out or drift.** Prefer the RCA tools —\n  `slow_query_rca` correlates digests, index usage and examined-row ratios\n  inside one call, so the model does not have to chain `top_queries`,\n  `explain_query` and `index_stats` and keep digests straight.\n- **The model ignores later tool results in a long context.** Statement digests\n  are the big payload here. Use `--limit` deliberately rather than pulling 200\n  digests when you want the top 10.\n- **The model describes calls instead of making them.** This is usually a\n  runtime/tool-calling-format mismatch, not a prompt problem — check that your\n  client advertises the tools in the format your model was trained on.\n\nFeedback on running this with a specific local model is genuinely useful —\nopen an issue at\n[github.com/AIops-tools/MySQL-AIops](https://github.com/AIops-tools/MySQL-AIops/issues)\nwith the model, runtime, and what went wrong.\n\nFile v0.10.3:references/capabilities.md\n\n# mysql-aiops capabilities\n\n> 35 MCP tools (26 read, 9 write); mock-validated, see `docs/VERIFICATION.md`. The\n> `information_schema` / `performance_schema` queries are modelled from\n> documented MySQL 8.x / MariaDB 10.6+ shapes and need live verification.\n> `top_queries` / `slow_query_rca` require `performance_schema=ON`; the read\n> account should have `PROCESS`, `REPLICATION CLIENT` and `SELECT` on\n> `performance_schema`.\n\n## Read tools (25)\n\n| Tool | Source | Returns |\n|------|--------|---------|\n| `overview` | several reads (resilient) | version, flavor, uptimeDays, readOnly, role, connections{}, sessionsByCommand, longestQuery, mostFragmentedTable, secondsBehindSource |\n| `server_version` | `version()`, `SHOW GLOBAL STATUS/VARIABLES` | version, flavor (mysql/mariadb), uptimeSeconds/Days, readOnly, superReadOnly, dataDirectory |\n| `show_variables` | `SHOW GLOBAL VARIABLES` | name, value (optional LIKE filter) |\n| `show_status` | `SHOW GLOBAL STATUS` | name, value (optional LIKE filter) |\n| `list_databases` | `information_schema.tables` | name, tableCount, data/index/totalBytes, totalPretty |\n| `list_engines` | `SHOW ENGINES` | engine, support, isDefault, transactions |\n| `connection_stats` | `SHOW GLOBAL STATUS/VARIABLES` | maxConnections, threadsConnected/Running, maxUsedConnections, abortedConnects, usedPct |\n| `list_sessions` | `information_schema.processlist` | total, byCommand, sleepingCount, sessions[] |\n| `long_running_queries` | processlist | thresholdSeconds, count, queries[] (oldest first) |\n| `list_transactions` | `information_schema.innodb_trx` | count, lockWaitCount, transactions[] (rowsLocked/Modified) |\n| `lock_waits` | `performance_schema.data_lock_waits` (MariaDB: `information_schema.innodb_lock_waits`) | pairs[] {blockedId, blockingId, waitSeconds, queries} |\n| `top_queries` | `events_statements_summary_by_digest` | statements[] (calls, total/mean ms, lockTimePct, noIndexUsedPct, rowsExaminedPerSent, tmpDiskTables) |\n| `explain_query` | `EXPLAIN FORMAT=JSON` | plan (JSON; planned, not executed) |\n| `unused_indexes` | `table_io_waits_summary_by_index_usage` | indexes[] with zero I/O since restart |\n| `redundant_indexes` | `information_schema.statistics` | redundant[] {index, coveredBy, exactDuplicate} |\n| `index_stats` | `information_schema.statistics` | indexes[] {columns, unique, cardinality} |\n| `table_sizes` | `information_schema.tables` | tables[] data/index/totalBytes, engine, estRows |\n| `table_fragmentation` | `information_schema.tables` | tables[] freeBytes (data_free), freePct |\n| `table_status` | `information_schema.tables` | tables[] engine, rowFormat, autoIncrement, updateTime; nonInnodbTables[] |\n| `replica_status` | `SHOW REPLICA STATUS` (MariaDB: `SHOW SLAVE STATUS`) | isReplica, replicas[] {ioThreadRunning, sqlThreadRunning, secondsBehindSource, lastIo/SqlError, gtid} |\n| `binlog_status` | `SHOW BINARY LOGS` + variables + processlist | logBin, serverId, binlogFormat, gtidMode, binlogCount/TotalBytes, downstreamReplicas[] |\n| `slow_query_rca` | digest rows + EXPLAIN | worst{}, planAccessTypes[], findings[] (cited cause/action) |\n| `lock_wait_rca` | lock-wait pairs + `SHOW ENGINE INNODB STATUS` | roots[], worstRootId, deadlockSuspected, lastDeadlock{victim, transactions} |\n| `replication_lag_rca` | replica status record | findings[] (IO/SQL thread stopped, lagging, intentional delay, healthy) |\n| `fragmentation_analysis` | fragmentation rows | recommendations[] (cited reasons + OPTIMIZE action) |\n\nThe flagship analyses accept injected records (`statements=` / `pairs=` /\n`status=` / `tables=`) for pure/offline analysis, or pull live from a\nconfigured `target`.\n\n## Write tools (8)\n\n| Tool | Risk | SQL | Undo / safety |\n|------|------|-----|---------------|\n| `kill_session` | **high** | `KILL CONNECTION <id>` | captures session user/host/query for audit; no safe inverse; dry-run + double-confirm |\n| `kill_query` | **high** | `KILL QUERY <id>` | captures session; session survives, statement aborted; no inverse; dry-run + double-confirm |\n| `drop_index` | **high** | `DROP INDEX ... ON ...` | rebuilds the definition from `SHOW CREATE TABLE` FIRST; undo = recreate exactly (replays via `create_index(definition=…)`); dry-run + double-confirm |\n| `optimize_table` | medium | `OPTIMIZE TABLE` | records prior size/data_free stats; no undo (rebuild) |\n| `analyze_table` | medium | `ANALYZE TABLE` | records prior stats; no undo |\n| `create_index` | medium | `CREATE [UNIQUE] INDEX` | returns created (table, name); undo = drop it |\n| `set_global_variable` | medium | `SET GLOBAL <name> = %s` | captures prior value from `SHOW GLOBAL VARIABLES`; undo = set back; runtime-only (persist yourself) |\n| `reset_query_stats` | medium | `TRUNCATE ...events_statements_summary_by_digest` | irreversible; no undo |\n\nAll values are bound query parameters; identifiers that cannot be parameterised\n(schema/table/index/column/variable names, ORDER BY columns) are validated\nagainst a strict identifier charset / allow-lists and backtick-quoted before\ninterpolation.\n\n## Flavor branching\n\n| Concern | MySQL 8.x | MariaDB 10.6+ |\n|---------|-----------|----------------|\n| Replica status | `SHOW REPLICA STATUS` (`Source_*`/`Replica_*` fields) | `SHOW SLAVE STATUS` (`Master_*`/`Slave_*` fields) |\n| Lock waits | `performance_schema.data_lock_waits` | `information_schema.innodb_lock_waits` |\n| Detection | `version()` without \"MariaDB\" | `version()` contains \"MariaDB\" |\n\nBoth result shapes are normalised into one record family; `doctor` and\n`overview` report the detected flavor.\n\n## Out of scope (by design)\n\n- Application-schema **migrations** / DDL beyond index maintenance\n- ORM / model management\n- Logical or physical **backup/restore** orchestration (mysqldump, PITR)\n- User/grant management and `CREATE`/`DROP DATABASE`\n- PostgreSQL (use **postgres-aiops**); OT / industrial equipment (use the\n  `industrial-aiops` line)\n\nWant one of these? Open an issue or PR — feedback and contributions welcome.\n\nFile v0.10.3:references/cli-reference.md\n\n# mysql-aiops CLI reference\n\n> The `information_schema` / `performance_schema` queries are modelled from documented\n> MySQL 8.x / MariaDB 10.6+ shapes and are mock-validated; see `docs/VERIFICATION.md`\n> for the live-run checklist.\n\n## Setup & diagnostics\n\n```bash\nmysql-aiops init                      # interactive onboarding wizard\nmysql-aiops doctor [--skip-auth]      # config + secrets + connectivity + flavor + perf-schema + replica role\nmysql-aiops overview [--target <t>]   # one-shot server health snapshot\nmysql-aiops mcp                       # start the MCP server (stdio transport)\n```\n\n## Secrets (encrypted store ~/.mysql-aiops/secrets.enc)\n\n```bash\nmysql-aiops secret set <target> [--value <pw>]    # store password (hidden prompt if no --value)\nmysql-aiops secret list                            # names only — values never shown\nmysql-aiops secret rm <target>\nmysql-aiops secret migrate                         # import legacy plaintext .env (MYSQL_<T>_PASSWORD)\nmysql-aiops secret rotate-password                 # re-encrypt under a new master password\n```\n\n## Read commands\n\n```bash\nmysql-aiops server version                 # version, flavor (mysql/mariadb), uptime, read_only\nmysql-aiops server variables [pattern]     # SHOW GLOBAL VARIABLES (optional name filter)\nmysql-aiops server status [pattern]        # SHOW GLOBAL STATUS (optional name filter)\nmysql-aiops server databases               # schemas + sizes\nmysql-aiops server engines                 # storage engines\nmysql-aiops server connections             # headroom vs max_connections\n\nmysql-aiops activity sessions [--no-sleeping]  # processlist + per-command counts\nmysql-aiops activity long [--min-seconds 60]\nmysql-aiops activity transactions          # open InnoDB transactions\nmysql-aiops activity lock-waits            # wait-for edges (flavor-branched)\n\nmysql-aiops query top [--order-by total_time] [--limit 20]   # statement digests\nmysql-aiops query explain \"<sql>\"          # EXPLAIN FORMAT=JSON (planned, not executed)\n\nmysql-aiops index unused                   # zero-I/O indexes since restart\nmysql-aiops index redundant                # prefix-covered / duplicate indexes\nmysql-aiops index stats                    # columns + cardinality\n\nmysql-aiops table sizes\nmysql-aiops table fragmentation            # data_free per table\nmysql-aiops table status                   # engine / row format / update time\n\nmysql-aiops repl status                    # replica threads + lag (flavor-branched)\nmysql-aiops repl binlog                    # binlog/GTID + downstream replicas\n\nmysql-aiops analyze slow-query [--explain \"<sql>\"]   # flagship RCA\nmysql-aiops analyze lock-waits             # chain + last deadlock\nmysql-aiops analyze replication            # lag/thread-state RCA\nmysql-aiops analyze fragmentation          # OPTIMIZE candidates\n```\n\n## Write commands (governed; risk tier in parentheses)\n\n```bash\nmysql-aiops remediate kill <id> [--dry-run]                    # (high) KILL CONNECTION; no undo; double confirm\nmysql-aiops remediate kill-query <id> [--dry-run]              # (high) KILL QUERY; no undo; double confirm\nmysql-aiops remediate drop-index <table> <name> [--dry-run]    # (high) reversible; double confirm\nmysql-aiops remediate optimize <table> [--dry-run]             # (medium) OPTIMIZE TABLE\nmysql-aiops remediate analyze-table <table> [--dry-run]        # (medium) ANALYZE TABLE\nmysql-aiops remediate create-index <table> <cols...> [--name N] [--unique] [--dry-run]  # (medium) reversible\nmysql-aiops remediate set <name> <value> [--dry-run]           # (medium) SET GLOBAL; reversible\nmysql-aiops query reset [--dry-run]                            # (medium) truncate digest stats\n```\n\n## Common options\n\n- `--target, -t <name>` — target name from `config.yaml` (omit to use the default/first target)\n- `--dry-run` — print the statement that would run, change nothing\n- State-changing commands require two confirmations at the CLI layer\n\nFile v0.10.3:references/setup-guide.md\n\n# mysql-aiops setup & security guide\n\n> Mock-validated; not yet run against a live MySQL / MariaDB server. `mysql-aiops doctor`\n> is the fastest live check — see `docs/VERIFICATION.md`.\n\n## 1. Install\n\n```bash\nuv tool install mysql-aiops\n```\n\n## 2. Prepare an account\n\nmysql-aiops connects with PyMySQL and reads `information_schema` /\n`performance_schema`. A least-privilege monitoring account works for the reads:\n\n```sql\nCREATE USER 'aiops'@'%' IDENTIFIED BY 'change-me';\nGRANT PROCESS, REPLICATION CLIENT ON *.* TO 'aiops'@'%';\nGRANT SELECT ON performance_schema.* TO 'aiops'@'%';\n-- performance_schema must be ON (default on MySQL 8.x) for query stats\n```\n\nMaintenance writes need more: `OPTIMIZE`/`ANALYZE`/`CREATE INDEX`/`DROP INDEX`\nrequire `ALTER` + `INDEX` (and `INSERT` for OPTIMIZE) on the target schema;\n`KILL` requires `CONNECTION_ADMIN` (or `SUPER`); `SET GLOBAL` requires\n`SYSTEM_VARIABLES_ADMIN` (or `SUPER`).\n\n## 3. Onboard\n\n```bash\nmysql-aiops init\n```\n\nThe wizard collects (non-secret) connection details into\n`~/.mysql-aiops/config.yaml` and stores the password **encrypted** into\n`~/.mysql-aiops/secrets.enc`. Example config:\n\n```yaml\ntargets:\n  - name: primary\n    host: 10.0.0.30\n    port: 3306\n    database: appdb\n    user: aiops\n    ssl_mode: verify_ca       # disabled/preferred/required/verify_ca/verify_identity\n    ssl_ca: /etc/ssl/mysql-ca.pem\n```\n\n## 4. Non-interactive use (MCP server / CI / cron)\n\nExport the master password so the encrypted store can be unlocked without a\nprompt:\n\n```bash\nexport MYSQL_AIOPS_MASTER_PASSWORD='your-master-password'\n```\n\n## Credential security\n\n- The password is **never** written to disk in plaintext. It lives only in\n  `~/.mysql-aiops/secrets.enc`, encrypted with Fernet (AES-128-CBC + HMAC),\n  the key derived from your master password via scrypt. Only a per-store random\n  salt and the ciphertext are on disk (chmod 600); the master password itself is\n  never stored.\n- A legacy plaintext env var `MYSQL_<TARGET_NAME_UPPER>_PASSWORD` is still\n  honoured as a fallback with a deprecation warning — migrate with\n  `mysql-aiops secret migrate` (it imports then renames the old `.env`).\n- The password is passed to `pymysql.connect` at connect time and held only in\n  memory; it is never logged or echoed. Exception text and tracebacks are\n  scrubbed of secret-shaped strings before being written to the audit log.\n\n## TLS\n\n`ssl_mode` follows MySQL client semantics and maps to PyMySQL TLS kwargs:\n\n| ssl_mode | Behaviour |\n|----------|-----------|\n| `disabled` | TLS off — isolated labs only |\n| `preferred` (default) | negotiate TLS when the server supports it |\n| `required` | force TLS, no certificate verification |\n| `verify_ca` | force TLS + verify the server cert against `ssl_ca` |\n| `verify_identity` | `verify_ca` + hostname check (recommended in production) |\n\n## SQL safety\n\n- All values (session ids, thresholds, limits, variable values) are **bound\n  query parameters** — never string-formatted into SQL.\n- The few identifiers that cannot be parameterised (schema/table/index/column\n  names, global variable names, `ORDER BY` columns) are validated against a\n  strict identifier charset / allow-lists and backtick-quoted before\n  interpolation; anything that is not a plain identifier is rejected.\n- `EXPLAIN` rejects multi-statement input (an embedded `;` is refused); the\n  `drop_index` undo replay is shape-gated to `CREATE [UNIQUE] INDEX` statements.\n\n## Governance harness state\n\nState lives under `~/.mysql-aiops/` (relocate with `MYSQL_AIOPS_HOME`):\n\n- `audit.db` — every tool call (SQLite), with risk tier and an optional approver/rationale\n  annotation (`MYSQL_AUDIT_APPROVED_BY` / `MYSQL_AUDIT_RATIONALE`) if you set one — never\n  required, never blocking\n- `undo.db` — inverse descriptors for reversible writes (e.g. `drop_index`)\n- budget / runaway guard — caps cumulative tool calls and wall-time; trips on\n  tight poll/retry loops\n\n## Verify\n\n```bash\nmysql-aiops doctor\n```\n\n`doctor` checks the config file, the encrypted store and its permissions, that a\npassword is present per target, and (unless `--skip-auth`) connectivity — then\nprobes `version()` (reporting the mysql/mariadb flavor), whether\n`performance_schema` is ON, and the replica role (`SHOW REPLICA STATUS`, or\n`SHOW SLAVE STATUS` on MariaDB).\n\nFile v0.10.3:skill-card.md\n\n## Description:\n\nProvides governed MySQL and MariaDB DBA operations for health checks, slow-query analysis, lock-wait and deadlock RCA, replication-lag RCA, fragmentation analysis, and guarded maintenance actions.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[zw008](https://clawhub.ai/user/zw008)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers, SREs, and database administrators use this skill to inspect and troubleshoot MySQL 8.x or MariaDB 10.6+ servers, interpret database health signals, and carry out guarded maintenance operations. It is intended for DBA workflows such as slow-query triage, index analysis, lock investigation, replication diagnostics, and controlled remediation.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can perform high-impact MySQL or MariaDB changes that affect live database availability and performance.\n\nMitigation: Begin with a least-privilege read-only database account, use dry runs, grant write privileges only during approved maintenance windows, and verify audit and undo behavior before production use.\n\nRisk: The release installs externally fetched DBA tooling and depends on package resolution at install or run time.\n\nMitigation: Pin and verify the package version where possible, install from trusted package sources, and review the resolved dependency set before connecting to production databases.\n\nRisk: Database credentials are stored locally and the master password may be supplied through environment variables for non-interactive use.\n\nMitigation: Use the encrypted credential store, avoid long-lived master-password environment variables, restrict local file permissions, and rotate credentials after shared or automated use.\n\nRisk: TLS defaults may not verify server identity on untrusted networks.\n\nMitigation: Set ssl_mode to verify_identity with a trusted CA for production or other untrusted network paths.\n\nRisk: Some database-query behavior is mock-validated and the artifact states it has not yet been exercised against a live server.\n\nMitigation: Run mysql-aiops doctor and validate core workflows against a staging or non-production database before relying on results for production remediation.\n\n## Reference(s):\n\n- [MySQL AIops homepage](https://github.com/AIops-tools/MySQL-AIops)\n- [ClawHub skill page](https://clawhub.ai/zw008/skills/mysql-aiops)\n- [capabilities.md](references/capabilities.md)\n- [cli-reference.md](references/cli-reference.md)\n- [setup-guide.md](references/setup-guide.md)\n- [agent-guardrails.md](references/agent-guardrails.md)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown guidance with CLI commands, configuration snippets, SQL previews, and structured database findings.]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May include measured DBA observations, risk-tiered remediation guidance, dry-run outputs, audit and undo notes, and tool-result summaries.]\n\n## Skill Version(s):\n\n0.10.3 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v0.10.2: 7 files, 19847 bytes\n\nFiles: references/agent-guardrails.md (6367b), references/capabilities.md (6001b), references/cli-reference.md (3976b), references/setup-guide.md (4324b), skill-card.md (2472b), SKILL.md (19002b), _meta.json (131b)\n\nFile v0.10.2:SKILL.md\n\n---\nname: mysql-aiops\nslug: mysql-aiops\ndisplayName: \"MySQL AIops\"\nsummary: \"Governed MySQL/MariaDB DBA ops: slow-query, lock-wait, replication & fragmentation RCA; 35 tools.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/MySQL-AIops\ntags: [aiops, mcp, governance, mysql]\ndescription: >\n  Use this skill whenever the user needs to operate or troubleshoot a MySQL 8.x or MariaDB 10.6+ server as a DBA — a one-shot server health overview (version + flavor, connection headroom, replica role); server reads (global variables, status counters, databases, storage engines); activity (sessions/processlist, long-running queries, open InnoDB transactions, lock waits); query stats (performance_schema statement-digest top-N, EXPLAIN FORMAT=JSON); index health (unused indexes, redundant/duplicate indexes, cardinality); table health (sizes, data_free fragmentation, engine/row-format status); replication (replica IO/SQL thread state and lag, binlog/GTID status); four flagship analyses — slow-query RCA (worst digest + EXPLAIN → cited cause/action incl. full-scan and lock-time-dominant classification), InnoDB lock-wait & deadlock chain RCA (wait-for tree, root blocker, last deadlock parsed from SHOW ENGINE INNODB STATUS), replication lag RCA (thread state/error fields → cause+action), and table fragmentation analysis (data_free → OPTIMIZE candidates); and guarded writes (kill a session or query, OPTIMIZE/ANALYZE TABLE, create/drop an index, SET GLOBAL a variable, reset digest stats).\n  Always use this skill for \"mysql health check\", \"why is this query slow\", \"top queries by time\", \"EXPLAIN this\", \"table fragmentation\", \"which indexes are unused\", \"redundant index\", \"who is blocking whom\", \"deadlock\", \"kill the session holding the lock\", \"replication lag\", \"replica stopped\", \"seconds behind master/source\", \"OPTIMIZE this table\", \"create/drop an index\", or \"SET GLOBAL max_connections\" when the context is a MySQL or MariaDB database.\n  Do NOT use for PostgreSQL — use postgres-aiops. Do NOT use when the target is OT / industrial equipment (use industrial-aiops), a hypervisor, a storage appliance, a backup product, or a container/cluster orchestrator (negative routing hints only).\n  Common MySQL/MariaDB DBA operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Behaviour is validated by a mock-based test suite; see docs/VERIFICATION.md for the live-verification checklist.\ninstaller:\n  kind: uv\n  package: mysql-aiops\nargument-hint: \"[session id / table / index name or describe your DBA task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"mysql-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"MYSQL_AIOPS_CONFIG\",\"MYSQL_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/MySQL-AIops\",\"emoji\":\"🐬\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed MySQL/MariaDB DBA operations. The governance harness (audit, policy, token/runaway budget, undo, risk-tiers) is bundled in the package — no external skill-family dependency. Connects via PyMySQL (30s timeouts) and reads information_schema / performance_schema; the server flavor (mysql vs mariadb) is detected from version() and flavor-dependent statements branch (SHOW REPLICA STATUS vs SHOW SLAVE STATUS; performance_schema.data_lock_waits vs information_schema.innodb_lock_waits).\n  All write operations are audited to a local SQLite DB under ~/.mysql-aiops/ (relocatable via MYSQL_AIOPS_HOME).\n  Credentials: the MySQL account password is stored ENCRYPTED in ~/.mysql-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'mysql-aiops init' to onboard, or 'mysql-aiops secret set <target>' to add one. The store is unlocked by a master password from MYSQL_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var MYSQL_<TARGET_NAME_UPPER>_PASSWORD is still honoured as a fallback with a deprecation warning (migrate with 'mysql-aiops secret migrate'). The password is passed to pymysql.connect at connect time and held only in memory; it is never logged or echoed.\n  SQL safety: all values are bound query parameters; the few identifiers that cannot be parameterised (schema/table/index/column/variable names, ORDER BY columns) are validated against a strict identifier charset / allow-lists and backtick-quoted before interpolation. EXPLAIN rejects multi-statement input; the drop_index undo replay path is shape-gated to CREATE [UNIQUE] INDEX statements.\n  State-changing operations require double confirmation at the CLI layer and support --dry-run. All write tools pass through the @governed_tool decorator (budget/runaway guard + audit + risk-tier label — it records, not authorizes) and take a dry_run preview. Reversible writes fetch the real before-state first and record a faithful inverse (create_index↔drop_index, where drop rebuilds the definition from SHOW CREATE TABLE; set_global_variable restores the prior value); irreversible ops (kill session/query, optimize/analyze, reset stats) record prior state only.\n  Webhooks: none — no outbound network calls beyond the configured MySQL connection.\n  TLS: ssl_mode follows MySQL client semantics (default preferred); set verify_ca/verify_identity (with ssl_ca) on untrusted networks.\n  Transitive dependencies: PyMySQL (pure-Python MySQL driver) and the MCP SDK. No post-install scripts or background services.\n  VERIFICATION: the information_schema / performance_schema queries are modelled from documented MySQL 8.x / MariaDB 10.6+ shapes and are validated by a mock-based test suite; they have not yet been exercised against a live server (see docs/VERIFICATION.md). Community-maintained; not affiliated with Oracle or the MariaDB Foundation — trademarks belong to their owners.\n---\n\n# MySQL AIops\n\n> **Disclaimer**: Community-maintained open-source project, **not affiliated with, endorsed by, or sponsored by Oracle Corporation or the MariaDB Foundation.** \"MySQL\" and \"MariaDB\" trademarks belong to their owners. Source at [github.com/AIops-tools/MySQL-AIops](https://github.com/AIops-tools/MySQL-AIops) under the MIT license.\n\nGoverned MySQL / MariaDB DBA operations — **35 MCP tools**, every one wrapped with the bundled `@governed_tool` harness: a local unified audit log under `~/.mysql-aiops/`, token/runaway budget guard, undo-token recording, and descriptive risk-tier labels. The account password is stored **encrypted** (`~/.mysql-aiops/secrets.enc`, Fernet + scrypt) — never plaintext on disk.\n\n> **Standalone**: the governance harness is bundled in the package (`mysql_aiops.governance`) — mysql-aiops has no external skill-family dependency. Behaviour is covered by a mock-based test suite; `docs/VERIFICATION.md` is the checklist for a live run against a real MySQL / MariaDB server.\n\n## What This Skill Does\n\n| Domain | Tools | Count | Read or Write |\n|--------|-------|:-----:|:-------------:|\n| **Overview** | server health snapshot (version+flavor, connections, replica role) | 1 | 1 read |\n| **Server** | version+flavor, variables, status, databases, engines, connection stats | 6 | 6 read |\n| **Activity** | sessions, long-running queries, transactions, lock waits | 4 | 4 read |\n| **Queries** | top-N statement digests, EXPLAIN FORMAT=JSON | 2 | 2 read |\n| **Indexes** | unused, redundant/duplicate, cardinality stats | 3 | 3 read |\n| **Tables** | sizes, data_free fragmentation, engine/row-format status | 3 | 3 read |\n| **Replication** | replica status/lag, binlog/GTID | 2 | 2 read |\n| **Analysis (flagship)** | slow-query RCA, lock-wait & deadlock RCA, replication-lag RCA, fragmentation | 4 | 4 read |\n| **Writes** | kill-session, kill-query, drop-index | 3 | 3 write (high) |\n| | optimize, analyze-table, create-index, SET GLOBAL, reset-stats | 5 | 5 write (medium) |\n| **Undo** | undo list, undo apply | 2 | 1 read / 1 write |\n\nThe flagship analyses accept injected records for pure/offline analysis, or pull live from a configured target. `top_queries` / `slow_query_rca` require `performance_schema=ON`; the read account should have `PROCESS`, `REPLICATION CLIENT` and `SELECT` on `performance_schema`.\n\n## Quick Install\n\n```bash\nuv tool install mysql-aiops\nmysql-aiops init       # interactive wizard: connection + encrypted password\nmysql-aiops doctor     # connectivity + flavor + performance_schema + replica role\n```\n\nOr as an OpenClaw plugin, which installs this skill and its MCP server together:\n\n```bash\nopenclaw plugins install clawhub:@zw008/mysql-aiops\nopenclaw skills info mysql-aiops          # expect: Visible to model: yes\n```\n\nNeeds `uvx` on `PATH`: the MCP server is fetched with uv, pinned to this release.\n\n## When to Use This Skill\n\n- Triage a server (`overview`): version + flavor, uptime, connection headroom, sessions by command, longest query, most fragmented table, replica role\n- Root-cause a slow query (`analyze slow-query` / `slow_query_rca`): the worst statement digest + EXPLAIN → cited cause and action (full scan, lock-time dominant, tmp-disk spill, N+1)\n- Untangle a lock pile-up or deadlock (`analyze lock-waits` / `lock_wait_rca`): the wait-for tree with the root blocker named + the last deadlock parsed from `SHOW ENGINE INNODB STATUS`\n- Diagnose replication (`analyze replication` / `replication_lag_rca`): IO/SQL thread state, `Seconds_Behind_Source`, error fields → cause + action\n- Decide what to OPTIMIZE (`analyze fragmentation` / `fragmentation_analysis`): tables ranked by reclaimable `data_free`\n- Find unused / redundant indexes; check table sizes and engines; inspect binlog/GTID state\n- Kill a session or its query, OPTIMIZE/ANALYZE a table, create/drop an index (reversible), or SET GLOBAL a variable — all with dry-run + double-confirm\n\n**Do NOT use for PostgreSQL — use postgres-aiops.** Do NOT use when the target is OT/industrial equipment (use industrial-aiops), a hypervisor, a storage appliance, a backup product, or a container cluster.\n\n## Related Skills — Skill Routing\n\n| If the user wants… | Use |\n|--------------------|-----|\n| MySQL / MariaDB DBA-ops: slow queries, lock waits, replication, fragmentation | **mysql-aiops** (this skill) |\n| PostgreSQL DBA-ops | **postgres-aiops** |\n| OT / industrial edge (Modbus, OPC-UA, PLC, PROFINET) | the **industrial-aiops** line |\n| Hypervisor VM lifecycle (power, snapshot, migrate) | a hypervisor ops skill |\n| Container/cluster lifecycle | a cluster ops skill |\n\n## Common Workflows\n\n### 1. \"The application is slow\" — from complaint to a working index\n\n1. `mysql-aiops doctor` → connectivity, detected flavor, and whether\n   `performance_schema` is actually enabled (if it is off, the digest-based analysis\n   below has nothing to read — fix that first).\n2. `mysql-aiops overview` → one-shot: version, connection counts, buffer-pool and\n   activity headline, so you know whether this is a query problem or a load problem.\n3. `mysql-aiops analyze slow-query` → the worst statement digests, each with cited\n   findings (full scan / no index used, lock time dominant, rows examined per row sent,\n   tmp-table spill to disk, high call count) and a concrete action per finding.\n4. `mysql-aiops query top --limit 20` → confirm the digest the RCA blamed really is the\n   top consumer, not a one-off.\n5. `mysql-aiops query explain \"<sql>\"` → read the actual plan. `access_type: ALL` on a\n   large table is the signature that an index will help; a plan already using an index\n   means the fix is elsewhere.\n6. `mysql-aiops index unused` and `mysql-aiops index redundant` → before adding one,\n   check you are not duplicating an index that already exists (a redundant index costs\n   writes and buys nothing).\n7. `mysql-aiops remediate create-index <table> <col> --name idx_x --dry-run` → prints\n   the exact DDL; re-run without `--dry-run` (double-confirm). The write is reversible\n   and records an inverse `drop_index` undo descriptor.\n8. Re-run `mysql-aiops query explain \"<sql>\"` and `analyze slow-query` to prove the plan\n   changed and the digest dropped.\n9. **Failure branch**: if the plan did not change, the optimizer may be working from\n   stale statistics — `mysql-aiops remediate analyze-table <table>` and re-check. If the\n   index made things *worse* (write amplification, or the optimizer picking it wrongly),\n   reverse it: `mysql-aiops undo list` → `mysql-aiops undo apply <id>` drops exactly the\n   index that was created. Index DDL on a large table can be long-running — if it stalls,\n   `mysql-aiops activity long --min-seconds 60` will show it, and cancelling mid-DDL is\n   its own risk, so size the table with `mysql-aiops table sizes` *before* step 7.\n\n### 2. A lock pile-up is stalling writes\n\n1. `mysql-aiops activity lock-waits` → the raw blocking/blocked pairs, straight from\n   the server.\n2. `mysql-aiops analyze lock-waits` → the wait-for tree resolved down to the **root\n   blocker** session, with the last deadlock (victim + both statements) attached.\n3. `mysql-aiops activity transactions` → what the root blocker is actually doing and how\n   long it has been open. An idle-in-transaction blocker is an application bug, not a\n   database one.\n4. `mysql-aiops activity sessions --no-sleeping` → confirm the blocker's user, host, and\n   statement before you touch it.\n5. Cancel the statement, not the connection, if that is enough:\n   `mysql-aiops remediate kill-query <session-id> --dry-run` then for real\n   (double-confirm). Escalate to `mysql-aiops remediate kill <session-id>` only if the\n   session must go.\n6. Re-run `mysql-aiops analyze lock-waits` → the tree should be empty.\n7. **Failure branch**: `kill` and `kill-query` are **irreversible — they record no\n   undo**, and killing a long-running transaction triggers a rollback that can itself\n   take a long time and hold locks meanwhile. If the tree does not clear, do not kill\n   more sessions in a loop (the runaway budget guard will stop you anyway): re-read\n   `activity transactions` to see whether the rollback is in progress, and go after the\n   application holding the transaction open instead.\n\n### 3. A replica has fallen behind\n\n1. `mysql-aiops analyze replication` → the cited cause: IO thread stopped (with the real\n   `Last_IO_Error`), SQL thread stopped (with `Last_SQL_Error`), applier simply lagging,\n   or an intentional `SQL_Delay`.\n2. `mysql-aiops repl status` → the raw replica record, so you can see the seconds-behind\n   value and thread states the analysis quoted. Note the tool branches on flavor\n   automatically (`SHOW REPLICA STATUS` on MySQL, `SHOW SLAVE STATUS` on MariaDB).\n3. `mysql-aiops repl binlog` → binlog position and retention, to judge whether the\n   replica can still catch up or has fallen off the end of the logs.\n4. `mysql-aiops overview` on the replica → check the lag is not just resource pressure\n   masquerading as a replication fault.\n5. Apply the cause-specific fix: connectivity/credentials for a stopped IO thread, the\n   diverged row for a stopped SQL thread, or parallel apply for a slow applier —\n   `mysql-aiops remediate set slave_parallel_workers 4 --dry-run` first (reversible; the\n   prior value is captured as the undo descriptor).\n6. **Failure branch**: an intentional `SQL_Delay` is *not* a fault — the analysis says so,\n   and \"fixing\" it defeats a deliberate safety window. If a `SET GLOBAL` made things\n   worse, `mysql-aiops undo apply <id>` restores the **prior** value. If the replica has\n   fallen off the retained binlogs, no setting will recover it — it needs a reseed, which\n   is out of this tool's scope.\n\n### 4. Reclaim space from a bloated table\n\n1. `mysql-aiops analyze fragmentation` → tables ranked by reclaimable `data_free`, each\n   citing the measured bytes.\n2. `mysql-aiops table sizes` and `mysql-aiops table fragmentation` → confirm the size and\n   free space independently, and see how big the rebuild will actually be.\n3. `mysql-aiops index unused` → while you are here, an index nothing has used is dead\n   weight; `mysql-aiops index stats` shows the usage numbers behind that claim.\n4. `mysql-aiops remediate drop-index <table> <index-name> --dry-run` then for real — the\n   write rebuilds the index definition from `SHOW CREATE TABLE` **before** dropping, so\n   the undo descriptor recreates exactly the index that existed.\n5. `mysql-aiops remediate optimize <table> --dry-run` → preview, then re-run to\n   `OPTIMIZE TABLE` (double-confirm).\n6. Re-run `mysql-aiops analyze fragmentation` to confirm the space came back.\n7. **Failure branch**: `OPTIMIZE TABLE` rebuilds the table and can lock or block writes\n   for the duration on a large table — run it in a maintenance window, and check\n   `mysql-aiops activity long` if the system goes quiet. It records **no** undo (there is\n   nothing to reverse). If dropping the index turned out to be wrong,\n   `mysql-aiops undo apply <id>` recreates it from the captured definition — this is the\n   one step in this recipe that *is* reversible, which is why it comes before the\n   OPTIMIZE.\n\n### Offline analysis (no live server)\n\nPass data straight to the analysis tools — `slow_query_rca(statements=[...])`, `lock_wait_rca(pairs=[...])`, `replication_lag_rca(status={...})`, or `fragmentation_analysis(tables=[...])` — to analyse an exported dataset without connecting.\n\n## Governance & Safety\n\nThe skill delivers reads and writes and records them; it does **not** decide whether a write is\npermitted. That is your agent's judgement, or the permission of the account you connect it with\n(point it at a MySQL/MariaDB account granted only SELECT / PROCESS / REPLICATION CLIENT and no\nwrite privileges (no INSERT/UPDATE/DELETE/DDL) — writes then fail at the server). There is no\nread-only switch, policy file, or approval gate.\n\n- **Audit is the guarantee, and it is not bypassable.** Every operation — MCP and CLI alike — is logged to `~/.mysql-aiops/audit.db` (relocatable via `MYSQL_AIOPS_HOME`): params, result, status, duration, and the risk tier. The CLI writes the same row the MCP path does.\n- `MYSQL_AUDIT_APPROVED_BY` / `MYSQL_AUDIT_RATIONALE` are optional annotations recorded on the audit row (who/why); they are never required and never block.\n- **Runaway guard** — a safety backstop, not authorization: the same call looped in a tight window trips a circuit breaker. Disable with `MYSQL_RUNAWAY_MAX=0`.\n- Writes support `--dry-run` / `dry_run=True` and double confirmation at the CLI.\n- Reversible writes fetch the real before-state and record an inverse descriptor; irreversible ops (kill session/query, optimize/analyze, reset stats) record prior state only.\n- All values are bound query parameters; identifiers that cannot be parameterised are validated and backtick-quoted.\n\n## References\n\n- `references/capabilities.md` — full tool + field reference\n- `references/cli-reference.md` — CLI command reference\n- `references/setup-guide.md` — onboarding, credentials, and connectivity\n\nFile v0.10.2:_meta.json\n\n{\n  \"ownerId\": \"kn7b067awq2s97bn3d7p5qfhw5827pxc\",\n  \"slug\": \"mysql-aiops\",\n  \"version\": \"0.10.2\",\n  \"publishedAt\": 1789223481670\n}\n\nFile v0.10.2:references/agent-guardrails.md\n\n# Agent guardrails — running mysql-aiops with a smaller / local model\n\nIf you drive these tools with a local model (Llama, Qwen, Mistral … via Goose,\nOllama, LM Studio, or any OpenAI-compatible runtime), you will get noticeably\nbetter results with a short system prompt. This page gives you one, and — more\nimportantly — tells you which guardrails you **no longer need to write**, because\nthe tool now enforces them itself.\n\nThe distinction matters. A guardrail in a prompt is a request. A guardrail in the\nharness is a guarantee. Anything below that we could move into the harness, we did.\n\n## What the tool now enforces — do not waste prompt budget on these\n\nAuthorization is not this tool's job — decide it via the account you connect with or the\nagent's prompt, not via a switch this skill provides. See below for the account-side way to\nget a read-only setup.\n\n| You might be tempted to prompt | Why you don't need to |\n|---|---|\n| \"Never write SQL that modifies data\" | The tool exposes no arbitrary-SQL surface at all. Every statement is built from a fixed template; identifiers are validated against a strict charset and backtick-quoted, and values are always bound as query parameters. `explain_query` runs `EXPLAIN`, not your statement. |\n| \"Don't invent a value when a field is missing\" | A NULL column comes back as `null`, never as `\"\"`. A sleeping session's `query` is `null` (it is running nothing), not blank; MariaDB's absent `gtid_mode` is `null`, not `\"\"`. |\n| \"Tell me if the output was cut off\" | `top_queries`, `table_sizes`, `table_fragmentation` and `table_status` return `{\"statements\"/\"tables\": [...], \"returned\": N, \"limit\": L, \"truncated\": true/false}`. Truncation is measured — one extra row is requested — not guessed from a length coincidence. |\n| \"Preserve the ordering / tell me what's most urgent\" | `slow_query_rca`, `lock_wait_rca` and `replication_lag_rca` rank findings worst-first with the measured number attached. Priority is in the payload, not implied by list position. |\n| \"Confirm before anything destructive\" | `drop_index`, `kill_query`/`kill_session` and `optimize_table` require a `--dry-run`-able preview plus double confirmation at the CLI. `drop_index` captures the index's `SHOW CREATE` definition first, so the undo token can recreate it exactly. |\n| \"Log what you did\" | Every governed call is audited to `~/.mysql-aiops/audit.db` regardless of what the model says it did. |\n\n## What still needs a prompt\n\nThese are model-behaviour problems the harness cannot fix from the outside.\nCopy this into your agent's system prompt:\n\n```text\nYou operate a MySQL or MariaDB server through the mysql-aiops MCP tools.\n\nTOOL USE\n- Before answering any question about the current database, you MUST call a\n  tool. Never answer from memory or assumption.\n- Actually invoke the tool. Do not describe the call you would make, and do not\n  emit an example JSON response in place of calling it.\n- If a tool call fails, report the real error verbatim. Never fill the gap with\n  a plausible-sounding answer.\n\nREADING RESULTS\n- Read the whole result before concluding. If a result contains a \"truncated\"\n  field that is true, say so and re-run with a higher limit. The slowest query\n  on the server may be the one just past the cut-off.\n- A null field means the server returned NULL or had no such value. Report it\n  as \"not available\" — never infer it. A session with a null \"query\" is idle,\n  not running an unknown statement.\n- Report values exactly as returned. Times are already converted to\n  milliseconds; do not re-scale them. Do not prettify digests or table names.\n- Cite the measured number. \"mean_time 240ms over 15,000 calls\" is useful;\n  \"this query is slow\" is not.\n\nSCOPE\n- Separate observation from interpretation. State what the tools returned, then\n  any interpretation, clearly marked as such.\n- Do not recommend an index unless unused_indexes / redundant_indexes or an\n  EXPLAIN in the result supports it. Adding an index is not free.\n- Do not attribute replication lag to a cause the replication tools did not\n  measure. Check whether the IO and SQL threads are actually running first.\n- Do not confuse a thread id with a digest, a schema with a table, or\n  rows_examined with rows_sent — the gap between those last two is the point.\n- MySQL and MariaDB differ. The flavor is reported by server_version; do not\n  suggest a MySQL-only feature (like gtid_mode) on MariaDB.\n- performance_schema may be OFF, in which case top_queries returns nothing.\n  That is a configuration fact, not \"the server has no slow queries\".\n```\n\n## Recommended setup for a local model\n\nPoint the tool at a read-only database account until you trust the setup — that is where\nthe guarantee actually lives, not in a switch this skill provides:\n\n```bash\nmysql-aiops doctor\n```\n\nGrant the connecting account only `SELECT`, `PROCESS` and `REPLICATION CLIENT` (no\n`INSERT`/`UPDATE`/`DELETE`/DDL); any write tool the model calls will then fail at the server.\nWhen you are ready to allow writes, grant the account write privileges and, if you want a\nname on the audit trail, set an approver annotation (optional — it is recorded, never\nrequired):\n\n```bash\nexport MYSQL_AUDIT_APPROVED_BY=\"your.name@example.com\"\nexport MYSQL_AUDIT_RATIONALE=\"index cleanup, change ticket DB-4412\"\n```\n\n## If your model still struggles\n\nSome behaviours are model-capacity limits rather than prompt problems:\n\n- **Multi-tool workflows time out or drift.** Prefer the RCA tools —\n  `slow_query_rca` correlates digests, index usage and examined-row ratios\n  inside one call, so the model does not have to chain `top_queries`,\n  `explain_query` and `index_stats` and keep digests straight.\n- **The model ignores later tool results in a long context.** Statement digests\n  are the big payload here. Use `--limit` deliberately rather than pulling 200\n  digests when you want the top 10.\n- **The model describes calls instead of making them.** This is usually a\n  runtime/tool-calling-format mismatch, not a prompt problem — check that your\n  client advertises the tools in the format your model was trained on.\n\nFeedback on running this with a specific local model is genuinely useful —\nopen an issue at\n[github.com/AIops-tools/MySQL-AIops](https://github.com/AIops-tools/MySQL-AIops/issues)\nwith the model, runtime, and what went wrong.\n\nFile v0.10.2:references/capabilities.md\n\n# mysql-aiops capabilities\n\n> 35 MCP tools (26 read, 9 write); mock-validated, see `docs/VERIFICATION.md`. The\n> `information_schema` / `performance_schema` queries are modelled from\n> documented MySQL 8.x / MariaDB 10.6+ shapes and need live verification.\n> `top_queries` / `slow_query_rca` require `performance_schema=ON`; the read\n> account should have `PROCESS`, `REPLICATION CLIENT` and `SELECT` on\n> `performance_schema`.\n\n## Read tools (25)\n\n| Tool | Source | Returns |\n|------|--------|---------|\n| `overview` | several reads (resilient) | version, flavor, uptimeDays, readOnly, role, connections{}, sessionsByCommand, longestQuery, mostFragmentedTable, secondsBehindSource |\n| `server_version` | `version()`, `SHOW GLOBAL STATUS/VARIABLES` | version, flavor (mysql/mariadb), uptimeSeconds/Days, readOnly, superReadOnly, dataDirectory |\n| `show_variables` | `SHOW GLOBAL VARIABLES` | name, value (optional LIKE filter) |\n| `show_status` | `SHOW GLOBAL STATUS` | name, value (optional LIKE filter) |\n| `list_databases` | `information_schema.tables` | name, tableCount, data/index/totalBytes, totalPretty |\n| `list_engines` | `SHOW ENGINES` | engine, support, isDefault, transactions |\n| `connection_stats` | `SHOW GLOBAL STATUS/VARIABLES` | maxConnections, threadsConnected/Running, maxUsedConnections, abortedConnects, usedPct |\n| `list_sessions` | `information_schema.processlist` | total, byCommand, sleepingCount, sessions[] |\n| `long_running_queries` | processlist | thresholdSeconds, count, queries[] (oldest first) |\n| `list_transactions` | `information_schema.innodb_trx` | count, lockWaitCount, transactions[] (rowsLocked/Modified) |\n| `lock_waits` | `performance_schema.data_lock_waits` (MariaDB: `information_schema.innodb_lock_waits`) | pairs[] {blockedId, blockingId, waitSeconds, queries} |\n| `top_queries` | `events_statements_summary_by_digest` | statements[] (calls, total/mean ms, lockTimePct, noIndexUsedPct, rowsExaminedPerSent, tmpDiskTables) |\n| `explain_query` | `EXPLAIN FORMAT=JSON` | plan (JSON; planned, not executed) |\n| `unused_indexes` | `table_io_waits_summary_by_index_usage` | indexes[] with zero I/O since restart |\n| `redundant_indexes` | `information_schema.statistics` | redundant[] {index, coveredBy, exactDuplicate} |\n| `index_stats` | `information_schema.statistics` | indexes[] {columns, unique, cardinality} |\n| `table_sizes` | `information_schema.tables` | tables[] data/index/totalBytes, engine, estRows |\n| `table_fragmentation` | `information_schema.tables` | tables[] freeBytes (data_free), freePct |\n| `table_status` | `information_schema.tables` | tables[] engine, rowFormat, autoIncrement, updateTime; nonInnodbTables[] |\n| `replica_status` | `SHOW REPLICA STATUS` (MariaDB: `SHOW SLAVE STATUS`) | isReplica, replicas[] {ioThreadRunning, sqlThreadRunning, secondsBehindSource, lastIo/SqlError, gtid} |\n| `binlog_status` | `SHOW BINARY LOGS` + variables + processlist | logBin, serverId, binlogFormat, gtidMode, binlogCount/TotalBytes, downstreamReplicas[] |\n| `slow_query_rca` | digest rows + EXPLAIN | worst{}, planAccessTypes[], findings[] (cited cause/action) |\n| `lock_wait_rca` | lock-wait pairs + `SHOW ENGINE INNODB STATUS` | roots[], worstRootId, deadlockSuspected, lastDeadlock{victim, transactions} |\n| `replication_lag_rca` | replica status record | findings[] (IO/SQL thread stopped, lagging, intentional delay, healthy) |\n| `fragmentation_analysis` | fragmentation rows | recommendations[] (cited reasons + OPTIMIZE action) |\n\nThe flagship analyses accept injected records (`statements=` / `pairs=` /\n`status=` / `tables=`) for pure/offline analysis, or pull live from a\nconfigured `target`.\n\n## Write tools (8)\n\n| Tool | Risk | SQL | Undo / safety |\n|------|------|-----|---------------|\n| `kill_session` | **high** | `KILL CONNECTION <id>` | captures session user/host/query for audit; no safe inverse; dry-run + double-confirm |\n| `kill_query` | **high** | `KILL QUERY <id>` | captures session; session survives, statement aborted; no inverse; dry-run + double-confirm |\n| `drop_index` | **high** | `DROP INDEX ... ON ...` | rebuilds the definition from `SHOW CREATE TABLE` FIRST; undo = recreate exactly (replays via `create_index(definition=…)`); dry-run + double-confirm |\n| `optimize_table` | medium | `OPTIMIZE TABLE` | records prior size/data_free stats; no undo (rebuild) |\n| `analyze_table` | medium | `ANALYZE TABLE` | records prior stats; no undo |\n| `create_index` | medium | `CREATE [UNIQUE] INDEX` | returns created (table, name); undo = drop it |\n| `set_global_variable` | medium | `SET GLOBAL <name> = %s` | captures prior value from `SHOW GLOBAL VARIABLES`; undo = set back; runtime-only (persist yourself) |\n| `reset_query_stats` | medium | `TRUNCATE ...events_statements_summary_by_digest` | irreversible; no undo |\n\nAll values are bound query parameters; identifiers that cannot be parameterised\n(schema/table/index/column/variable names, ORDER BY columns) are validated\nagainst a strict identifier charset / allow-lists and backtick-quoted before\ninterpolation.\n\n## Flavor branching\n\n| Concern | MySQL 8.x | MariaDB 10.6+ |\n|---------|-----------|----------------|\n| Replica status | `SHOW REPLICA STATUS` (`Source_*`/`Replica_*` fields) | `SHOW SLAVE STATUS` (`Master_*`/`Slave_*` fields) |\n| Lock waits | `performance_schema.data_lock_waits` | `information_schema.innodb_lock_waits` |\n| Detection | `version()` without \"MariaDB\" | `version()` contains \"MariaDB\" |\n\nBoth result shapes are normalised into one record family; `doctor` and\n`overview` report the detected flavor.\n\n## Out of scope (by design)\n\n- Application-schema **migrations** / DDL beyond index maintenance\n- ORM / model management\n- Logical or physical **backup/restore** orchestration (mysqldump, PITR)\n- User/grant management and `CREATE`/`DROP DATABASE`\n- PostgreSQL (use **postgres-aiops**); OT / industrial equipment (use the\n  `industrial-aiops` line)\n\nWant one of these? Open an issue or PR — feedback and contributions welcome.\n\nFile v0.10.2:references/cli-reference.md\n\n# mysql-aiops CLI reference\n\n> The `information_schema` / `performance_schema` queries are modelled from documented\n> MySQL 8.x / MariaDB 10.6+ shapes and are mock-validated; see `docs/VERIFICATION.md`\n> for the live-run checklist.\n\n## Setup & diagnostics\n\n```bash\nmysql-aiops init                      # interactive onboarding wizard\nmysql-aiops doctor [--skip-auth]      # config + secrets + connectivity + flavor + perf-schema + replica role\nmysql-aiops overview [--target <t>]   # one-shot server health snapshot\nmysql-aiops mcp                       # start the MCP server (stdio transport)\n```\n\n## Secrets (encrypted store ~/.mysql-aiops/secrets.enc)\n\n```bash\nmysql-aiops secret set <target> [--value <pw>]    # store password (hidden prompt if no --value)\nmysql-aiops secret list                            # names only — values never shown\nmysql-aiops secret rm <target>\nmysql-aiops secret migrate                         # import legacy plaintext .env (MYSQL_<T>_PASSWORD)\nmysql-aiops secret rotate-password                 # re-encrypt under a new master password\n```\n\n## Read commands\n\n```bash\nmysql-aiops server version                 # version, flavor (mysql/mariadb), uptime, read_only\nmysql-aiops server variables [pattern]     # SHOW GLOBAL VARIABLES (optional name filter)\nmysql-aiops server status [pattern]        # SHOW GLOBAL STATUS (optional name filter)\nmysql-aiops server databases               # schemas + sizes\nmysql-aiops server engines                 # storage engines\nmysql-aiops server connections             # headroom vs max_connections\n\nmysql-aiops activity sessions [--no-sleeping]  # processlist + per-command counts\nmysql-aiops activity long [--min-seconds 60]\nmysql-aiops activity transactions          # open InnoDB transactions\nmysql-aiops activity lock-waits            # wait-for edges (flavor-branched)\n\nmysql-aiops query top [--order-by total_time] [--limit 20]   # statement digests\nmysql-aiops query explain \"<sql>\"          # EXPLAIN FORMAT=JSON (planned, not executed)\n\nmysql-aiops index unused                   # zero-I/O indexes since restart\nmysql-aiops index redundant                # prefix-covered / duplicate indexes\nmysql-aiops index stats                    # columns + cardinality\n\nmysql-aiops table sizes\nmysql-aiops table fragmentation            # data_free per table\nmysql-aiops table status                   # engine / row format / update time\n\nmysql-aiops repl status                    # replica threads + lag (flavor-branched)\nmysql-aiops repl binlog                    # binlog/GTID + downstream replicas\n\nmysql-aiops analyze slow-query [--explain \"<sql>\"]   # flagship RCA\nmysql-aiops analyze lock-waits             # chain + last deadlock\nmysql-aiops analyze replication            # lag/thread-state RCA\nmysql-aiops analyze fragmentation          # OPTIMIZE candidates\n```\n\n## Write commands (governed; risk tier in parentheses)\n\n```bash\nmysql-aiops remediate kill <id> [--dry-run]                    # (high) KILL CONNECTION; no undo; double confirm\nmysql-aiops remediate kill-query <id> [--dry-run]              # (high) KILL QUERY; no undo; double confirm\nmysql-aiops remediate drop-index <table> <name> [--dry-run]    # (high) reversible; double confirm\nmysql-aiops remediate optimize <table> [--dry-run]             # (medium) OPTIMIZE TABLE\nmysql-aiops remediate analyze-table <table> [--dry-run]        # (medium) ANALYZE TABLE\nmysql-aiops remediate create-index <table> <cols...> [--name N] [--unique] [--dry-run]  # (medium) reversible\nmysql-aiops remediate set <name> <value> [--dry-run]           # (medium) SET GLOBAL; reversible\nmysql-aiops query reset [--dry-run]                            # (medium) truncate digest stats\n```\n\n## Common options\n\n- `--target, -t <name>` — target name from `config.yaml` (omit to use the default/first target)\n- `--dry-run` — print the statement that would run, change nothing\n- State-changing commands require two confirmations at the CLI layer\n\nFile v0.10.2:references/setup-guide.md\n\n# mysql-aiops setup & security guide\n\n> Mock-validated; not yet run against a live MySQL / MariaDB server. `mysql-aiops doctor`\n> is the fastest live check — see `docs/VERIFICATION.md`.\n\n## 1. Install\n\n```bash\nuv tool install mysql-aiops\n```\n\n## 2. Prepare an account\n\nmysql-aiops connects with PyMySQL and reads `information_schema` /\n`performance_schema`. A least-privilege monitoring account works for the reads:\n\n```sql\nCREATE USER 'aiops'@'%' IDENTIFIED BY 'change-me';\nGRANT PROCESS, REPLICATION CLIENT ON *.* TO 'aiops'@'%';\nGRANT SELECT ON performance_schema.* TO 'aiops'@'%';\n-- performance_schema must be ON (default on MySQL 8.x) for query stats\n```\n\nMaintenance writes need more: `OPTIMIZE`/`ANALYZE`/`CREATE INDEX`/`DROP INDEX`\nrequire `ALTER` + `INDEX` (and `INSERT` for OPTIMIZE) on the target schema;\n`KILL` requires `CONNECTION_ADMIN` (or `SUPER`); `SET GLOBAL` requires\n`SYSTEM_VARIABLES_ADMIN` (or `SUPER`).\n\n## 3. Onboard\n\n```bash\nmysql-aiops init\n```\n\nThe wizard collects (non-secret) connection details into\n`~/.mysql-aiops/config.yaml` and stores the password **encrypted** into\n`~/.mysql-aiops/secrets.enc`. Example config:\n\n```yaml\ntargets:\n  - name: primary\n    host: 10.0.0.30\n    port: 3306\n    database: appdb\n    user: aiops\n    ssl_mode: verify_ca       # disabled/preferred/required/verify_ca/verify_identity\n    ssl_ca: /etc/ssl/mysql-ca.pem\n```\n\n## 4. Non-interactive use (MCP server / CI / cron)\n\nExport the master password so the encrypted store can be unlocked without a\nprompt:\n\n```bash\nexport MYSQL_AIOPS_MASTER_PASSWORD='your-master-password'\n```\n\n## Credential security\n\n- The password is **never** written to disk in plaintext. It lives only in\n  `~/.mysql-aiops/secrets.enc`, encrypted with Fernet (AES-128-CBC + HMAC),\n  the key derived from your master password via scrypt. Only a per-store random\n  salt and the ciphertext are on disk (chmod 600); the master password itself is\n  never stored.\n- A legacy plaintext env var `MYSQL_<TARGET_NAME_UPPER>_PASSWORD` is still\n  honoured as a fallback with a deprecation warning — migrate with\n  `mysql-aiops secret migrate` (it imports then renames the old `.env`).\n- The password is passed to `pymysql.connect` at connect time and held only in\n  memory; it is never logged or echoed. Exception text and tracebacks are\n  scrubbed of secret-shaped strings before being written to the audit log.\n\n## TLS\n\n`ssl_mode` follows MySQL client semantics and maps to PyMySQL TLS kwargs:\n\n| ssl_mode | Behaviour |\n|----------|-----------|\n| `disabled` | TLS off — isolated labs only |\n| `preferred` (default) | negotiate TLS when the server supports it |\n| `required` | force TLS, no certificate verification |\n| `verify_ca` | force TLS + verify the server cert against `ssl_ca` |\n| `verify_identity` | `verify_ca` + hostname check (recommended in production) |\n\n## SQL safety\n\n- All values (session ids, thresholds, limits, variable values) are **bound\n  query parameters** — never string-formatted into SQL.\n- The few identifiers that cannot be parameterised (schema/table/index/column\n  names, global variable names, `ORDER BY` columns) are validated against a\n  strict identifier charset / allow-lists and backtick-quoted before\n  interpolation; anything that is not a plain identifier is rejected.\n- `EXPLAIN` rejects multi-statement input (an embedded `;` is refused); the\n  `drop_index` undo replay is shape-gated to `CREATE [UNIQUE] INDEX` statements.\n\n## Governance harness state\n\nState lives under `~/.mysql-aiops/` (relocate with `MYSQL_AIOPS_HOME`):\n\n- `audit.db` — every tool call (SQLite), with risk tier and an optional approver/rationale\n  annotation (`MYSQL_AUDIT_APPROVED_BY` / `MYSQL_AUDIT_RATIONALE`) if you set one — never\n  required, never blocking\n- `undo.db` — inverse descriptors for reversible writes (e.g. `drop_index`)\n- budget / runaway guard — caps cumulative tool calls and wall-time; trips on\n  tight poll/retry loops\n\n## Verify\n\n```bash\nmysql-aiops doctor\n```\n\n`doctor` checks the config file, the encrypted store and its permissions, that a\npassword is present per target, and (unless `--skip-auth`) connectivity — then\nprobes `version()` (reporting the mysql/mariadb flavor), whether\n`performance_schema` is ON, and the replica role (`SHOW REPLICA STATUS`, or\n`SHOW SLAVE STATUS` on MariaDB).\n\nFile v0.10.2:skill-card.md\n\n## Description:\n\nmysql-aiops helps agents operate and troubleshoot MySQL 8.x and MariaDB 10.6+ servers with health checks, root-cause analysis for slow queries, lock waits, replication lag and fragmentation, plus guarded maintenance commands.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[zw008](https://clawhub.ai/user/zw008)\n\n### License/Terms of Use:\n\nMIT\n\n## Use Case:\n\nDevelopers, database administrators, and operations engineers use this skill to investigate MySQL or MariaDB server health, query performance, locking, replication, index health, table fragmentation, and maintenance actions through audited DBA workflows.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill exposes high-impact MySQL and MariaDB maintenance writes to agents without an enforced approval or read-only gate.\n\nMitigation: Use a dedicated least-privilege read-only database account by default, enable write privileges only for deliberate maintenance sessions, and rely on dry-run previews plus operator confirmation before writes.\n\nRisk: Database credentials and transport settings can create exposure if long-lived secrets or weak TLS modes are used.\n\nMitigation: Avoid exporting long-lived master passwords, prefer verify_identity TLS with a CA on untrusted networks, and install only from pinned trusted package or plugin releases.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/zw008/skills/mysql-aiops)\n- [Project homepage](https://github.com/AIops-tools/MySQL-AIops)\n- [Capabilities reference](references/capabilities.md)\n- [CLI reference](references/cli-reference.md)\n- [Setup and security guide](references/setup-guide.md)\n- [Agent guardrails](references/agent-guardrails.md)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown guidance with CLI commands and structured tool-output summaries]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May include database observations, root-cause findings, dry-run maintenance commands, configuration steps, and safety notes.]\n\n## Skill Version(s):\n\n0.10.2 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v0.10.1: 7 files, 19907 bytes\n\nFiles: references/agent-guardrails.md (6367b), references/capabilities.md (6001b), references/cli-reference.md (3976b), references/setup-guide.md (4324b), skill-card.md (2723b), SKILL.md (19008b), _meta.json (131b)\n\nFile v0.10.1:SKILL.md\n\n---\nname: mysql-aiops\nslug: mysql-aiops\ndisplayName: \"MySQL AIops\"\nsummary: \"Governed MySQL/MariaDB DBA ops: slow-query, lock-wait, replication & fragmentation RCA; 35 tools.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/MySQL-AIops\ntags: [aiops, mcp, governance, mysql]\ndescription: >\n  Use this skill whenever the user needs to operate or troubleshoot a MySQL 8.x or MariaDB 10.6+ server as a DBA — a one-shot server health overview (version + flavor, connection headroom, replica role); server reads (global variables, status counters, databases, storage engines); activity (sessions/processlist, long-running queries, open InnoDB transactions, lock waits); query stats (performance_schema statement-digest top-N, EXPLAIN FORMAT=JSON); index health (unused indexes, redundant/duplicate indexes, cardinality); table health (sizes, data_free fragmentation, engine/row-format status); replication (replica IO/SQL thread state and lag, binlog/GTID status); four flagship analyses — slow-query RCA (worst digest + EXPLAIN → cited cause/action incl. full-scan and lock-time-dominant classification), InnoDB lock-wait & deadlock chain RCA (wait-for tree, root blocker, last deadlock parsed from SHOW ENGINE INNODB STATUS), replication lag RCA (thread state/error fields → cause+action), and table fragmentation analysis (data_free → OPTIMIZE candidates); and guarded writes (kill a session or query, OPTIMIZE/ANALYZE TABLE, create/drop an index, SET GLOBAL a variable, reset digest stats).\n  Always use this skill for \"mysql health check\", \"why is this query slow\", \"top queries by time\", \"EXPLAIN this\", \"table fragmentation\", \"which indexes are unused\", \"redundant index\", \"who is blocking whom\", \"deadlock\", \"kill the session holding the lock\", \"replication lag\", \"replica stopped\", \"seconds behind master/source\", \"OPTIMIZE this table\", \"create/drop an index\", or \"SET GLOBAL max_connections\" when the context is a MySQL or MariaDB database.\n  Do NOT use for PostgreSQL — use postgres-aiops. Do NOT use when the target is OT / industrial equipment (use industrial-aiops), a hypervisor, a storage appliance, a backup product, or a container/cluster orchestrator (negative routing hints only).\n  Common MySQL/MariaDB DBA operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Behaviour is validated by a mock-based test suite; see docs/VERIFICATION.md for the live-verification checklist.\ninstaller:\n  kind: uv\n  package: mysql-aiops\nargument-hint: \"[session id / table / index name or describe your DBA task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"mysql-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"MYSQL_AIOPS_CONFIG\",\"MYSQL_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/MySQL-AIops\",\"emoji\":\"🐬\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed MySQL/MariaDB DBA operations. The governance harness (audit, policy, token/runaway budget, undo, risk-tiers) is bundled in the package — no external skill-family dependency. Connects via PyMySQL (30s timeouts) and reads information_schema / performance_schema; the server flavor (mysql vs mariadb) is detected from version() and flavor-dependent statements branch (SHOW REPLICA STATUS vs SHOW SLAVE STATUS; performance_schema.data_lock_waits vs information_schema.innodb_lock_waits).\n  All write operations are audited to a local SQLite DB under ~/.mysql-aiops/ (relocatable via MYSQL_AIOPS_HOME).\n  Credentials: the MySQL account password is stored ENCRYPTED in ~/.mysql-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'mysql-aiops init' to onboard, or 'mysql-aiops secret set <target>' to add one. The store is unlocked by a master password from MYSQL_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var MYSQL_<TARGET_NAME_UPPER>_PASSWORD is still honoured as a fallback with a deprecation warning (migrate with 'mysql-aiops secret migrate'). The password is passed to pymysql.connect at connect time and held only in memory; it is never logged or echoed.\n  SQL safety: all values are bound query parameters; the few identifiers that cannot be parameterised (schema/table/index/column/variable names, ORDER BY columns) are validated against a strict identifier charset / allow-lists and backtick-quoted before interpolation. EXPLAIN rejects multi-statement input; the drop_index undo replay path is shape-gated to CREATE [UNIQUE] INDEX statements.\n  State-changing operations require double confirmation at the CLI layer and support --dry-run. All write tools pass through the @governed_tool decorator (budget/runaway guard + audit + risk-tier label — it records, not authorizes) and take a dry_run preview. Reversible writes fetch the real before-state first and record a faithful inverse (create_index↔drop_index, where drop rebuilds the definition from SHOW CREATE TABLE; set_global_variable restores the prior value); irreversible ops (kill session/query, optimize/analyze, reset stats) record prior state only.\n  Webhooks: none — no outbound network calls beyond the configured MySQL connection.\n  TLS: ssl_mode follows MySQL client semantics (default preferred); set verify_ca/verify_identity (with ssl_ca) on untrusted networks.\n  Transitive dependencies: PyMySQL (pure-Python MySQL driver) and the MCP SDK. No post-install scripts or background services.\n  VERIFICATION: the information_schema / performance_schema queries are modelled from documented MySQL 8.x / MariaDB 10.6+ shapes and are validated by a mock-based test suite; they have not yet been exercised against a live server (see docs/VERIFICATION.md). Community-maintained; not affiliated with Oracle or the MariaDB Foundation — trademarks belong to their owners.\n---\n\n# MySQL AIops\n\n> **Disclaimer**: Community-maintained open-source project, **not affiliated with, endorsed by, or sponsored by Oracle Corporation or the MariaDB Foundation.** \"MySQL\" and \"MariaDB\" trademarks belong to their owners. Source at [github.com/AIops-tools/MySQL-AIops](https://github.com/AIops-tools/MySQL-AIops) under the MIT license.\n\nGoverned MySQL / MariaDB DBA operations — **35 MCP tools**, every one wrapped with the bundled `@governed_tool` harness: a local unified audit log under `~/.mysql-aiops/`, token/runaway budget guard, undo-token recording, and descriptive risk-tier labels. The account password is stored **encrypted** (`~/.mysql-aiops/secrets.enc`, Fernet + scrypt) — never plaintext on disk.\n\n> **Standalone**: the governance harness is bundled in the package (`mysql_aiops.governance`) — mysql-aiops has no external skill-family dependency. Behaviour is covered by a mock-based test suite; `docs/VERIFICATION.md` is the checklist for a live run against a real MySQL / MariaDB server.\n\n## What This Skill Does\n\n| Domain | Tools | Count | Read or Write |\n|--------|-------|:-----:|:-------------:|\n| **Overview** | server health snapshot (version+flavor, connections, replica role) | 1 | 1 read |\n| **Server** | version+flavor, variables, status, databases, engines, connection stats | 6 | 6 read |\n| **Activity** | sessions, long-running queries, transactions, lock waits | 4 | 4 read |\n| **Queries** | top-N statement digests, EXPLAIN FORMAT=JSON | 2 | 2 read |\n| **Indexes** | unused, redundant/duplicate, cardinality stats | 3 | 3 read |\n| **Tables** | sizes, data_free fragmentation, engine/row-format status | 3 | 3 read |\n| **Replication** | replica status/lag, binlog/GTID | 2 | 2 read |\n| **Analysis (flagship)** | slow-query RCA, lock-wait & deadlock RCA, replication-lag RCA, fragmentation | 4 | 4 read |\n| **Writes** | kill-session, kill-query, drop-index | 3 | 3 write (high) |\n| | optimize, analyze-table, create-index, SET GLOBAL, reset-stats | 5 | 5 write (medium) |\n| **Undo** | undo list, undo apply | 2 | 1 read / 1 write |\n\nThe flagship analyses accept injected records for pure/offline analysis, or pull live from a configured target. `top_queries` / `slow_query_rca` require `performance_schema=ON`; the read account should have `PROCESS`, `REPLICATION CLIENT` and `SELECT` on `performance_schema`.\n\n## Quick Install\n\n```bash\nuv tool install mysql-aiops\nmysql-aiops init       # interactive wizard: connection + encrypted password\nmysql-aiops doctor     # connectivity + flavor + performance_schema + replica role\n```\n\nOr as an OpenClaw plugin, which installs this skill and its MCP server together:\n\n```bash\nopenclaw plugins install clawhub:@aiops-tools/mysql-aiops\nopenclaw skills info mysql-aiops          # expect: Visible to model: yes\n```\n\nNeeds `uvx` on `PATH`: the MCP server is fetched with uv, pinned to this release.\n\n## When to Use This Skill\n\n- Triage a server (`overview`): version + flavor, uptime, connection headroom, sessions by command, longest query, most fragmented table, replica role\n- Root-cause a slow query (`analyze slow-query` / `slow_query_rca`): the worst statement digest + EXPLAIN → cited cause and action (full scan, lock-time dominant, tmp-disk spill, N+1)\n- Untangle a lock pile-up or deadlock (`analyze lock-waits` / `lock_wait_rca`): the wait-for tree with the root blocker named + the last deadlock parsed from `SHOW ENGINE INNODB STATUS`\n- Diagnose replication (`analyze replication` / `replication_lag_rca`): IO/SQL thread state, `Seconds_Behind_Source`, error fields → cause + action\n- Decide what to OPTIMIZE (`analyze fragmentation` / `fragmentation_analysis`): tables ranked by reclaimable `data_free`\n- Find unused / redundant indexes; check table sizes and engines; inspect binlog/GTID state\n- Kill a session or its query, OPTIMIZE/ANALYZE a table, create/drop an index (reversible), or SET GLOBAL a variable — all with dry-run + double-confirm\n\n**Do NOT use for PostgreSQL — use postgres-aiops.** Do NOT use when the target is OT/industrial equipment (use industrial-aiops), a hypervisor, a storage appliance, a backup product, or a container cluster.\n\n## Related Skills — Skill Routing\n\n| If the user wants… | Use |\n|--------------------|-----|\n| MySQL / MariaDB DBA-ops: slow queries, lock waits, replication, fragmentation | **mysql-aiops** (this skill) |\n| PostgreSQL DBA-ops | **postgres-aiops** |\n| OT / industrial edge (Modbus, OPC-UA, PLC, PROFINET) | the **industrial-aiops** line |\n| Hypervisor VM lifecycle (power, snapshot, migrate) | a hypervisor ops skill |\n| Container/cluster lifecycle | a cluster ops skill |\n\n## Common Workflows\n\n### 1. \"The application is slow\" — from complaint to a working index\n\n1. `mysql-aiops doctor` → connectivity, detected flavor, and whether\n   `performance_schema` is actually enabled (if it is off, the digest-based analysis\n   below has nothing to read — fix that first).\n2. `mysql-aiops overview` → one-shot: version, connection counts, buffer-pool and\n   activity headline, so you know whether this is a query problem or a load problem.\n3. `mysql-aiops analyze slow-query` → the worst statement digests, each with cited\n   findings (full scan / no index used, lock time dominant, rows examined per row sent,\n   tmp-table spill to disk, high call count) and a concrete action per finding.\n4. `mysql-aiops query top --limit 20` → confirm the digest the RCA blamed really is the\n   top consumer, not a one-off.\n5. `mysql-aiops query explain \"<sql>\"` → read the actual plan. `access_type: ALL` on a\n   large table is the signature that an index will help; a plan already using an index\n   means the fix is elsewhere.\n6. `mysql-aiops index unused` and `mysq\n\nArchive v0.10.0: 7 files, 19894 bytes\n\nFiles: references/agent-guardrails.md (6367b), references/capabilities.md (6001b), references/cli-reference.md (3976b), references/setup-guide.md (4324b), skill-card.md (2972b), SKILL.md (18698b), _meta.json (131b)\n\nArchive v0.9.0: 7 files, 19970 bytes\n\nFiles: references/agent-guardrails.md (6367b), references/capabilities.md (6001b), references/cli-reference.md (3976b), references/setup-guide.md (4324b), skill-card.md (3152b), SKILL.md (18800b), _meta.json (130b)\n\nArchive v0.8.0: 7 files, 19897 bytes\n\nFiles: references/agent-guardrails.md (6367b), references/capabilities.md (6001b), references/cli-reference.md (3976b), references/setup-guide.md (4324b), skill-card.md (2887b), SKILL.md (18800b), _meta.json (130b)\n\nArchive v0.7.0: 7 files, 19927 bytes\n\nFiles: references/agent-guardrails.md (6367b), references/capabilities.md (6001b), references/cli-reference.md (3976b), references/setup-guide.md (4324b), skill-card.md (2969b), SKILL.md (18800b), _meta.json (130b)\n\nArchive v0.6.0: 7 files, 19816 bytes\n\nFiles: references/agent-guardrails.md (6367b), references/capabilities.md (6001b), references/cli-reference.md (3976b), references/setup-guide.md (4324b), skill-card.md (2839b), SKILL.md (18800b), _meta.json (130b)\n\nArchive v0.5.0: 7 files, 19840 bytes\n\nFiles: references/agent-guardrails.md (6367b), references/capabilities.md (6001b), references/cli-reference.md (3976b), references/setup-guide.md (4324b), skill-card.md (2790b), SKILL.md (18800b), _meta.json (130b)","readmeExcerpt":"Skill: mysql-aiops Owner: zw008 Summary: Use this skill whenever the user needs to operate or troubleshoot a MySQL 8.x or MariaDB 10.6+ server as a DBA — a one-shot server health overview (version + flavor, connection headroom, replica role); server reads (global variables, status counters, databases, storage engines); activity (sessions/processlist, long-running queries, open InnoDB transactions, lock waits); query ","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"uv tool install mysql-aiops\nmysql-aiops init       # interactive wizard: connection + encrypted password\nmysql-aiops doctor     # connectivity + flavor + performance_schema + replica role"},{"language":"bash","snippet":"openclaw plugins install clawhub:@zw008/mysql-aiops\nopenclaw skills info mysql-aiops          # expect: Visible to model: yes"},{"language":"text","snippet":"You operate a MySQL or MariaDB server through the mysql-aiops MCP tools.\n\nTOOL USE\n- Before answering any question about the current database, you MUST call a\n  tool. Never answer from memory or assumption.\n- Actually invoke the tool. Do not describe the call you would make, and do not\n  emit an example JSON response in place of calling it.\n- If a tool call fails, report the real error verbatim. Never fill the gap with\n  a plausible-sounding answer.\n\nREADING RESULTS\n- Read the whole result before concluding. If a result contains a \"truncated\"\n  field that is true, say so and re-run with a higher limit. The slowest query\n  on the server may be the one just past the cut-off.\n- Findings from `slow_query_rca` and `replication_lag_rca` are NOT ordered by severity and\n  carry no rank. Weigh each finding's own numbers and say which one you acted on; never\n  treat the first as the headline.\n- A null field means the server returned NULL or had no such value. Report it\n  as \"not available\" — never infer it. A session with a null \"query\" is idle,\n  not running an unknown statement.\n- Report values exactly as returned. Times are already converted to\n  milliseconds; do not re-scale them. Do not prettify digests or table names.\n- Cite the measured number. \"mean_time 240ms over 15,000 calls\" is useful;\n  \"this query is slow\" is not.\n\nSCOPE\n- Separate observation from interpretation. State what the tools returned, then\n  any interpretation, clearly marked as such.\n- Do not recommend an index unless unused_indexes / redundant_indexes or an\n  EXPLAIN in the result supports it. Adding an index is not free.\n- Do not attribute replication lag to a cause the replication tools did not\n  measure. Check whether the IO and SQL threads are actually running first.\n- Do not confuse a thread id with a digest, a schema with a table, or\n  rows_examined with rows_sent — the gap between those last two is the point.\n- MySQL and MariaDB differ. The flavor is reported by server_version; do not\n  sugges"},{"language":"bash","snippet":"mysql-aiops doctor"},{"language":"bash","snippet":"export MYSQL_AUDIT_APPROVED_BY=\"your.name@example.com\"\nexport MYSQL_AUDIT_RATIONALE=\"index cleanup, change ticket DB-4412\""},{"language":"bash","snippet":"mysql-aiops init                      # interactive onboarding wizard\nmysql-aiops doctor [--skip-auth]      # config + secrets + connectivity + flavor + perf-schema + replica role\nmysql-aiops overview [--target <t>]   # one-shot server health snapshot\nmysql-aiops mcp                       # start the MCP server (stdio transport)"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: mysql-aiops\nslug: mysql-aiops\ndisplayName: \"MySQL AIops\"\nsummary: \"Governed MySQL/MariaDB DBA ops: slow-query, lock-wait, replication & fragmentation RCA; 35 tools.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/MySQL-AIops\ntags: [aiops, mcp, governance, mysql]\ndescription: >\n  Use this skill whenever the user needs to operate or troubleshoot a MySQL 8.x or MariaDB 10.6+ server as a DBA — a one-shot server health overview (version + flavor, connection headroom, replica role); server reads (global variables, status counters, databases, storage engines); activity (sessions/processlist, long-running queries, open InnoDB transactions, lock waits); query stats (performance_schema statement-digest top-N, EXPLAIN FORMAT=JSON); index health (unused indexes, redundant/duplicate indexes, cardinality); table health (sizes, data_free fragmentation, engine/row-format status); replication (replica IO/SQL thread state and lag, binlog/GTID status); four flagship analyses — slow-query RCA (worst digest + EXPLAIN → cited cause/action incl. full-scan and lock-time-dominant classification), InnoDB lock-wait & deadlock chain RCA (wait-for tree, root blocker, last deadlock parsed from SHOW ENGINE INNODB STATUS), replication lag RCA (thread state/error fields → cause+action), and table fragmentation analysis (data_free → OPTIMIZE candidates); and guarded writes (kill a session or query, OPTIMIZE/ANALYZE TABLE, create/drop an index, SET GLOBAL a variable, reset digest stats).\n  Always use this skill for \"mysql health check\", \"why is this query slow\", \"top queries by time\", \"EXPLAIN this\", \"table fragmentation\", \"which indexes are unused\", \"redundant index\", \"who is blocking whom\", \"deadlock\", \"kill the session holding the lock\", \"replication lag\", \"replica stopped\", \"seconds behind master/source\", \"OPTIMIZE this table\", \"create/drop an index\", or \"SET GLOBAL max_connections\" when the context is a MySQL or MariaDB database.\n  Do NOT use for PostgreSQL — use postgres-aiops. Do NOT use when the target is OT / industrial equipment (use industrial-aiops), a hypervisor, a storage appliance, a backup product, or a container/cluster orchestrator (negative routing hints only).\n  Common MySQL/MariaDB DBA operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Behaviour is validated by a mock-based test suite; see docs/VERIFICATION.md for the live-verification checklist.\ninstaller:\n  kind: uv\n  package: mysql-aiops\nargument-hint: \"[session id / table / index name or describe your DBA task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"mysql-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"MYSQL_AIOPS_CONFIG\",\"MYSQL_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/MySQL-AIops\",\"emoji\":\"🐬\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed MySQL/MariaDB DBA operations. The governance harness (audit, policy, token/runaway budget, undo, risk-tiers) is bundled in the package — no"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7b067awq2s97bn3d7p5qfhw5827pxc\",\n  \"slug\": \"mysql-aiops\",\n  \"version\": \"0.10.4\",\n  \"publishedAt\": 1789601168267\n}"},{"path":"references/agent-guardrails.md","content":"# Agent guardrails — running mysql-aiops with a smaller / local model\n\nIf you drive these tools with a local model (Llama, Qwen, Mistral … via Goose,\nOllama, LM Studio, or any OpenAI-compatible runtime), you will get noticeably\nbetter results with a short system prompt. This page gives you one, and — more\nimportantly — tells you which guardrails you **no longer need to write**, because\nthe tool now enforces them itself.\n\nThe distinction matters. A guardrail in a prompt is a request. A guardrail in the\nharness is a guarantee. Anything below that we could move into the harness, we did.\n\n## What the tool now enforces — do not waste prompt budget on these\n\nAuthorization is not this tool's job — decide it via the account you connect with or the\nagent's prompt, not via a switch this skill provides. See below for the account-side way to\nget a read-only setup.\n\n| You might be tempted to prompt | Why you don't need to |\n|---|---|\n| \"Never write SQL that modifies data\" | The tool exposes no arbitrary-SQL surface at all. Every statement is built from a fixed template; identifiers are validated against a strict charset and backtick-quoted, and values are always bound as query parameters. `explain_query` runs `EXPLAIN`, not your statement. |\n| \"Don't invent a value when a field is missing\" | A NULL column comes back as `null`, never as `\"\"`. A sleeping session's `query` is `null` (it is running nothing), not blank; MariaDB's absent `gtid_mode` is `null`, not `\"\"`. |\n| \"Tell me if the output was cut off\" | `top_queries`, `table_sizes`, `table_fragmentation` and `table_status` return `{\"statements\"/\"tables\": [...], \"returned\": N, \"limit\": L, \"truncated\": true/false}`. Truncation is measured — one extra row is requested — not guessed from a length coincidence. |\n| \"Make it show the number it judged on\" | Every finding cites the values that tripped it — `noIndexUsedPct`, `rowsExaminedPerSent`, `lockTimePct`, `tmpDiskTables` and `calls` for a statement (the `worst` block additionally reports `meanTimeMs` and `totalTimeMs`, which no check is tripped by); `ioThreadRunning`, `sqlThreadRunning` and `secondsBehindSource` for a replica — so a claim can be checked against a figure rather than taken on the model's word. `lock_wait_rca` returns no findings at all: it gives you `roots` ordered by `blockedCount` plus `worstRootId`, which names the blocker outright. |\n| \"Confirm before anything destructive\" | `drop_index`, `kill_query`/`kill_session` and `optimize_table` require a `--dry-run`-able preview plus double confirmation at the CLI. `drop_index` captures the index's `SHOW CREATE` definition first, so the undo token can recreate it exactly. |\n| \"Log what you did\" | Every governed call is audited to `~/.mysql-aiops/audit.db` regardless of what the model says it did. |\n\n## What still needs a prompt\n\nThese are model-behaviour problems the harness cannot fix from the outside.\n\n⚠️ **Do not read priority off list position — except from `lock_wait_rca`.** `slow_query_rca`\nan"},{"path":"references/capabilities.md","content":"# mysql-aiops capabilities\n\n> 35 MCP tools (26 read, 9 write); mock-validated, see `docs/VERIFICATION.md`. The\n> `information_schema` / `performance_schema` queries are modelled from\n> documented MySQL 8.x / MariaDB 10.6+ shapes and need live verification.\n> `top_queries` / `slow_query_rca` require `performance_schema=ON`; the read\n> account should have `PROCESS`, `REPLICATION CLIENT` and `SELECT` on\n> `performance_schema`.\n\n## Read tools (25)\n\n| Tool | Source | Returns |\n|------|--------|---------|\n| `overview` | several reads (resilient) | version, flavor, uptimeDays, readOnly, role, connections{}, sessionsByCommand, longestQuery, mostFragmentedTable, secondsBehindSource |\n| `server_version` | `version()`, `SHOW GLOBAL STATUS/VARIABLES` | version, flavor (mysql/mariadb), uptimeSeconds/Days, readOnly, superReadOnly, dataDirectory |\n| `show_variables` | `SHOW GLOBAL VARIABLES` | name, value (optional LIKE filter) |\n| `show_status` | `SHOW GLOBAL STATUS` | name, value (optional LIKE filter) |\n| `list_databases` | `information_schema.tables` | name, tableCount, data/index/totalBytes, totalPretty |\n| `list_engines` | `SHOW ENGINES` | engine, support, isDefault, transactions |\n| `connection_stats` | `SHOW GLOBAL STATUS/VARIABLES` | maxConnections, threadsConnected/Running, maxUsedConnections, abortedConnects, usedPct |\n| `list_sessions` | `information_schema.processlist` | total, byCommand, sleepingCount, sessions[] |\n| `long_running_queries` | processlist | thresholdSeconds, count, queries[] (oldest first) |\n| `list_transactions` | `information_schema.innodb_trx` | count, lockWaitCount, transactions[] (rowsLocked/Modified) |\n| `lock_waits` | `performance_schema.data_lock_waits` (MariaDB: `information_schema.innodb_lock_waits`) | pairs[] {blockedId, blockingId, waitSeconds, queries} |\n| `top_queries` | `events_statements_summary_by_digest` | statements[] (calls, total/mean ms, lockTimePct, noIndexUsedPct, rowsExaminedPerSent, tmpDiskTables) |\n| `explain_query` | `EXPLAIN FORMAT=JSON` | plan (JSON; planned, not executed) |\n| `unused_indexes` | `table_io_waits_summary_by_index_usage` | indexes[] with zero I/O since restart |\n| `redundant_indexes` | `information_schema.statistics` | redundant[] {index, coveredBy, exactDuplicate} |\n| `index_stats` | `information_schema.statistics` | indexes[] {columns, unique, cardinality} |\n| `table_sizes` | `information_schema.tables` | tables[] data/index/totalBytes, engine, estRows |\n| `table_fragmentation` | `information_schema.tables` | tables[] freeBytes (data_free), freePct |\n| `table_status` | `information_schema.tables` | tables[] engine, rowFormat, autoIncrement, updateTime; nonInnodbTables[] |\n| `replica_status` | `SHOW REPLICA STATUS` (MariaDB: `SHOW SLAVE STATUS`) | isReplica, replicas[] {ioThreadRunning, sqlThreadRunning, secondsBehindSource, lastIo/SqlError, gtid} |\n| `binlog_status` | `SHOW BINARY LOGS` + variables + processlist | logBin, serverId, binlogFormat, gtidMode, binlogCount/TotalBytes, downstre"},{"path":"references/cli-reference.md","content":"# mysql-aiops CLI reference\n\n> The `information_schema` / `performance_schema` queries are modelled from documented\n> MySQL 8.x / MariaDB 10.6+ shapes and are mock-validated; see `docs/VERIFICATION.md`\n> for the live-run checklist.\n\n## Setup & diagnostics\n\n```bash\nmysql-aiops init                      # interactive onboarding wizard\nmysql-aiops doctor [--skip-auth]      # config + secrets + connectivity + flavor + perf-schema + replica role\nmysql-aiops overview [--target <t>]   # one-shot server health snapshot\nmysql-aiops mcp                       # start the MCP server (stdio transport)\n```\n\n## Secrets (encrypted store ~/.mysql-aiops/secrets.enc)\n\n```bash\nmysql-aiops secret set <target> [--value <pw>]    # store password (hidden prompt if no --value)\nmysql-aiops secret list                            # names only — values never shown\nmysql-aiops secret rm <target>\nmysql-aiops secret migrate                         # import legacy plaintext .env (MYSQL_<T>_PASSWORD)\nmysql-aiops secret rotate-password                 # re-encrypt under a new master password\n```\n\n## Read commands\n\n```bash\nmysql-aiops server version                 # version, flavor (mysql/mariadb), uptime, read_only\nmysql-aiops server variables [pattern]     # SHOW GLOBAL VARIABLES (optional name filter)\nmysql-aiops server status [pattern]        # SHOW GLOBAL STATUS (optional name filter)\nmysql-aiops server databases               # schemas + sizes\nmysql-aiops server engines                 # storage engines\nmysql-aiops server connections             # headroom vs max_connections\n\nmysql-aiops activity sessions [--no-sleeping]  # processlist + per-command counts\nmysql-aiops activity long [--min-seconds 60]\nmysql-aiops activity transactions          # open InnoDB transactions\nmysql-aiops activity lock-waits            # wait-for edges (flavor-branched)\n\nmysql-aiops query top [--order-by total_time] [--limit 20]   # statement digests\nmysql-aiops query explain \"<sql>\"          # EXPLAIN FORMAT=JSON (planned, not executed)\n\nmysql-aiops index unused                   # zero-I/O indexes since restart\nmysql-aiops index redundant                # prefix-covered / duplicate indexes\nmysql-aiops index stats                    # columns + cardinality\n\nmysql-aiops table sizes\nmysql-aiops table fragmentation            # data_free per table\nmysql-aiops table status                   # engine / row format / update time\n\nmysql-aiops repl status                    # replica threads + lag (flavor-branched)\nmysql-aiops repl binlog                    # binlog/GTID + downstream replicas\n\nmysql-aiops analyze slow-query [--explain \"<sql>\"]   # flagship RCA\nmysql-aiops analyze lock-waits             # chain + last deadlock\nmysql-aiops analyze replication            # lag/thread-state RCA\nmysql-aiops analyze fragmentation          # OPTIMIZE candidates\n```\n\n## Write commands (governed; risk tier in parentheses)\n\n```bash\nmysql-aiops remediate kill <id> [--dry-run]                    # (high) KILL CONNECTIO"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":2092,"uniquenessScore":40,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T13:26:20.307Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-10T13:26:20.307Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T15:52:51.575Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}