@neverinfamous/mysql-mcp 3.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -312,7 +312,7 @@ jobs:
312
312
  password: ${{ secrets.DOCKER_PASSWORD }}
313
313
  repository: ${{ env.IMAGE_NAME }}
314
314
  readme-filepath: ./DOCKER_README.md
315
- short-description: "MySQL MCP Server: 192 tools, Code Mode, Tool Filtering, Connection Pooling, HTTP/SSE & OAuth 2.1"
315
+ short-description: "MySQL MCP Server: 192 Tools, Sandboxed Code Mode, Tool Filtering, Pooling, HTTP/SSE & OAuth 2.1."
316
316
 
317
317
  - name: Deployment Summary
318
318
  if: github.ref == 'refs/heads/main'
package/CHANGELOG.md CHANGED
@@ -1,10 +1,17 @@
1
- # Changelog
1
+ # Changelog
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [3.0.1] - 2026-02-26
9
+
10
+ ### Fixed
11
+
12
+ - **CodeQL Alert #23** — Removed unused `ValidationError` import in `security_integration.test.ts`
13
+ - **CodeQL Alert #24** — Removed unused `beforeEach` import in `sandbox-factory.test.ts`
14
+
8
15
  ## [3.0.0] - 2026-02-26
9
16
 
10
17
  ### Added
@@ -17,111 +24,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
17
24
  - **`mysql_security_audit` `eventType` Description Accuracy** — Updated parameter description from misleading `"CONNECT"`, `"QUERY"` examples to accurate `performance_schema` event names (`"Execute"`, `"Ping"`, `"begin"`), and documented LIKE matching behavior
18
25
  - **ServerInstructions Audit Fallback Documentation** — Split the security enterprise features bullet to separately document `mysql_security_audit` fallback behavior: `performance_schema` fallback mode, `startTime` filter limitations, `eventType` LIKE matching, and default limit
19
26
 
20
- ### Fixed
21
-
22
- - **No-Argument Prompts Zod Validation Error** — All 9 prompts without required arguments (`mysql_tool_index`, `mysql_setup_router`, `mysql_setup_proxysql`, `mysql_setup_shell`, `mysql_setup_events`, `mysql_sys_schema_guide`, `mysql_setup_spatial`, `mysql_setup_cluster`, `mysql_setup_docstore`) failed with `MCP error -32602: Invalid arguments ... expected object, received undefined` when invoked. Root cause: `DatabaseAdapter.registerPrompt()` always passed `argsSchema: {}` to the SDK even for no-argument prompts, which created `z.object({})` and rejected `undefined` input from clients. Fixed by passing `argsSchema: undefined` when `prompt.arguments` is empty
23
-
24
- - **All Prompts with Arguments — Zod Validation Error** — All 10 prompts with arguments (`mysql_quick_schema`, `mysql_database_health_check`, `mysql_backup_strategy`, `mysql_index_tuning`, `mysql_setup_replication`, `mysql_query_builder`, `mysql_quick_query`, `mysql_schema_design`, `mysql_performance_analysis`, `mysql_migration`) failed with `MCP error -32602: Invalid arguments ... expected object, received undefined` when invoked without arguments. Root cause: `DatabaseAdapter.registerPrompt()` built a Zod schema whenever `prompt.arguments.length > 0`, and the SDK wrapped it into `z.object({...})` via `normalizeObjectSchema()`. Even with all fields marked `.optional()`, `z.object().safeParse(undefined)` always rejects `undefined` input — making field-level optionality irrelevant. Two previous fix attempts addressed field-level optionality (`.optional()`, handler-level validation) but not the schema-level rejection. Definitive fix: `argsSchema` is now always `undefined` for all prompts, so the SDK skips Zod validation entirely. Handler-level required-arg validation (already present) returns a helpful guide message when required arguments are missing
25
-
26
- - **`mysql_doc_list_collections` False-Positive Collection Detection** — Detection query only checked for a `doc JSON` column without verifying `_id` column existence, causing any table with a `doc JSON` column (e.g., `test_json_docs`) to be listed as a document collection. Added `_id` column check via `JOIN` on `information_schema.COLUMNS`, matching the documented heuristic ("tables containing a `doc JSON` column with an `_id` field")
27
-
28
- - **Docstore Schema Detection (7 Tools)** — `mysql_doc_find`, `mysql_doc_add`, `mysql_doc_modify`, `mysql_doc_remove`, `mysql_doc_create_index`, `mysql_doc_create_collection`, and `mysql_doc_drop_collection` incorrectly returned `{ exists: false, collection }` or leaked raw SQL errors when a nonexistent `schema` parameter was provided. Upgraded `checkCollectionExists` to a discriminated return type that distinguishes schema-not-found from collection-not-found, added `ER_BAD_DB_ERROR` catch to `create_collection`, and added schema pre-check to `drop_collection`. All 7 tools now consistently return `{ exists: false, schema }` for nonexistent schemas, matching the P154 pattern
29
- - **Security Tool Error-Field Consistency (3 Handlers)** — Three security tool error paths (`mysql_security_audit` access-denied, `mysql_security_firewall_status` plugin check failure, `mysql_security_firewall_rules` table access error) returned `{ success: false, message }` without the standard `error` field, making them inconsistent with the `{ success: false, error }` convention used across all other tools. Added `error` field to all three responses (keeping `message` for backward compatibility)
30
- - **Security Tool Redundant `message` Field Removal (3 Handlers)** — Three security tool error paths (`mysql_security_audit` access-denied, `mysql_security_firewall_status` plugin check failure, `mysql_security_firewall_rules` table access error) returned both `error` and `message` fields with identical or redundant content. Removed the `message` field from all three, standardizing on the `error` field exclusively for `{ success: false }` responses
31
- - **`mysql_security_ssl_status` Empty Cipher Default** — The `str()` helper in `encryption.ts` treated empty strings as valid, so `currentCipher` returned `""` instead of `"None"` when SSL was disabled (MySQL returns `Ssl_cipher: ""`). Changed `str()` to treat empty strings as absent, activating the `"None"` default. Same fix applies to `sslVersion` (`"N/A"` default) and `requireSecureTransport` (`"OFF"` default)
32
- - **Security Tool Catch-Block Error Shape Consistency** — Three catch blocks in `audit.ts` returned domain-specific shapes (`{ available: false }`, `{ installed: false }`) without `success: false`, making them inconsistent with the `{ success: false, error }` convention used across all other tools. Added `success: false` to `mysql_security_audit` (audit-related errors), `mysql_security_firewall_rules` (table access errors), and `mysql_security_firewall_status` (plugin check failures)
33
-
34
- - **Schema Tool Zod Validation Leaks (6 Handlers)** — All 6 schema handler files (`constraints.ts`, `scheduled_events.ts`, `views.ts`, `management.ts`, `routines.ts`, `triggers.ts`) called `Schema.parse(params)` outside any `try/catch` block, causing raw Zod validation errors to propagate as MCP exceptions. Additionally, `list_constraints` (`type`), `list_events` (`status`), and `create_view` (`algorithm`, `checkOption`) used `z.enum()` directly on their `inputSchema`, causing the MCP framework to reject invalid values with raw `-32602` errors before handlers could intercept. Applied Split Schema pattern: created permissive `*Base` schemas with `z.string()` for `inputSchema` visibility, kept strict `z.enum()` schemas for handler-level parsing inside `try/catch` with `ZodError` detection and `formatZodError()` formatting, matching the Dual-Schema pattern used by admin, backup, and other tool groups
35
- - **`mysql_check_table` Zod Enum Validation Leak** — The `option` parameter used `z.enum()` on `CheckTableSchemaBase`, causing invalid option values (e.g., `"INVALID_OPTION"`) to be rejected at the MCP framework level with a raw `-32602` Zod validation error before the handler's `try/catch` could intercept. Widened to `z.string()` on the Base schema while keeping `z.enum()` on the handler-parsed `CheckTableSchema`, so invalid values are caught inside `try/catch` and returned as `{ success: false, error }`
36
- - **`mysql_binlog_events` Negative Limit Acceptance** — `BinlogEventsSchema` used `z.number().optional()` without `.nonnegative()`, allowing negative `limit` values (e.g., `-1`) to pass Zod validation and be string-interpolated into SQL via `LIMIT ${limit}`, producing a raw MySQL syntax error. Added `.nonnegative()` so negative values are rejected at the Zod validation level with structured `{ success: false, error }` responses
37
- - **`mysql_binlog_events` Zod Parse Outside `try/catch` / Split Schema Violation** — `BinlogEventsSchema.parse(params)` was called outside the handler's `try/catch` block, and the same strict schema was used as `inputSchema`, causing Zod validation errors to propagate as raw MCP `-32602` exceptions. Applied Split Schema pattern: created permissive `BinlogEventsSchemaBase` for `inputSchema` visibility, kept strict `BinlogEventsSchema` (with `.nonnegative()`) for handler parsing inside a new outer `try/catch` with `ZodError` detection and human-readable error formatting
38
-
39
- - **`mysql_flush_tables` Missing `error` Field on Nonexistent Tables** — When called with nonexistent tables, the response returned `{ success: false, notFound, flushed }` without the standard `error` field required by the error consistency convention. Added `error: "Tables not found: ..."` to the response, matching the `{ success: false, error }` pattern used by all other tools. The `notFound` and `flushed` arrays remain as additional context
40
-
41
- - **`mysql_json_index_suggest` DDL for Qualified Table Names** — Generated `indexDdl` wrapped qualified table names in a single backtick pair (`` `schema.table` ``) instead of properly escaping each part (`` `schema`.`table` ``), producing invalid MySQL syntax. The index name also included the schema prefix (e.g., `idx_schema.table_key`), which is invalid as an unquoted identifier. Fixed by using `escapeQualifiedTable()` for the `ALTER TABLE` clause and extracting just the table basename for the index name
42
- - **Transaction Tool Zod Validation Leaks (`mysql_transaction_begin`, `mysql_transaction_execute`)** — Both tools used `z.enum()` for their `isolationLevel` parameter, and called Zod's `parse()` outside their `try/catch` blocks (or lacked `try/catch` entirely). This caused invalid enum values to be rejected with raw `-32602` errors before the handler could intercept them. Applied Split Schema pattern with widened `z.string()` base schemas, moved `parse()` inside `try/catch`, and returned structured `{ success: false, error }` responses for validation failures.
43
- - **Core Tool Zod Validation Leaks (8 Tools)** — `mysql_read_query`, `mysql_write_query`, `mysql_list_tables`, `mysql_describe_table`, `mysql_create_table`, `mysql_drop_table`, `mysql_get_indexes`, and `mysql_create_index` called `Schema.parse(params)` outside their `try/catch` blocks, causing raw Zod validation errors to propagate as MCP exceptions when missing required parameters or invalid types were passed. Moved all `parse()` calls inside `try/catch` with `ZodError` detection and human-readable error formatting, matching the pattern used by all other tool groups.
44
- - **`mysql_drop_table` Default Behavior** — The `ifExists` parameter in `DropTableSchemaBase` defaulted to `true`, contradicting the documented behavior and generic SQL defaults where it should be false unless explicitly requested. Changed the default value to `false`.
45
-
46
- ### Security
47
-
48
- - **Worker Sandbox API Bridge (Critical)** — The `CODEMODE_ISOLATION=worker` mode spawned a Worker thread but the `mysql.*` API bindings were non-functional — `serializeBindings()` stripped all functions to method name arrays, and `worker-script.ts` set `mysql: {}` (empty object). Implemented a `MessagePort`-based RPC bridge: the main thread listens on `port1` for `{ id, group, method, args }` requests and dispatches to real `MySQLAdapter` methods; the worker builds async proxy stubs via `buildMysqlProxy()` that send RPC requests through `port2` and await responses. Changed default sandbox mode from `vm` to `worker` for stronger V8 isolate separation. Readonly enforcement, `resourceLimits` memory caps, and timeout mechanisms remain fully functional
49
-
50
- - **Code Mode Readonly Enforcement (Critical)** — The `readonly: true` flag on `mysql_execute_code` was accepted but never enforced — write tools (`writeQuery`, `dropTable`, `createTable`, `createIndex`) executed normally. Readonly mode now replaces write-oriented tool groups (`transactions`, `admin`, `backup`, `partitioning`, `roles`, `events`, `shell`) with stubs returning `{ success: false, error }`, and blocks individual write methods in mixed groups (`core`, `docstore`, `schema`, `json`, `fulltext`, `spatial`) with descriptive error messages
51
- - **Worker Memory Limits Enforced (Critical)** — `WorkerSandbox` now passes `resourceLimits` (`maxOldGenerationSizeMb`, `maxYoungGenerationSizeMb`) to the `Worker` constructor, enforcing V8 heap limits. Previously, `memoryLimitMb` in sandbox options was accepted but ignored
52
- - **Core Tool Group Scope Mapping (High)** — Fixed `core` tool group OAuth scope from `READ` → `WRITE`. The `core` group contains `writeQuery`, `dropTable`, `createTable`, and `createIndex`, which are write/DDL operations. A `READ`-scoped OAuth client could previously execute arbitrary write operations through `core` tools
53
- - **HTTP Security Headers (Medium)** — Added `Strict-Transport-Security` (2-year max-age), `Referrer-Policy` (no-referrer), and `Permissions-Policy` (camera/microphone/geolocation denied) to all HTTP transport responses, complementing existing CSP, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, and Cache-Control headers
54
- - **Sandbox Blocked Pattern Hardening (Medium)** — Added detection for bracket-notation constructor access (`['constructor']`) and `Reflect.construct` bypass vectors, closing two confirmed regex blocklist gaps in Code Mode security validation
55
-
56
- ### Fixed
57
-
58
- - **Router 404 Response Differentiation** — All 9 router tools returned `{ available: false, error }` for both "Router is down" (ECONNREFUSED, timeout, TLS, 401/500) and "route/metadata/pool not found" (404) scenarios, making them indistinguishable. `routerFetch` now attaches `statusCode` to thrown errors and `safeRouterFetch` detects 404 responses, returning `{ success: false, error }` (standard error convention) instead of `{ available: false }` (reserved for actual connectivity failures)
59
- - **`ConnectionPoolStatusSchema` Field Mismatch** — Schema defined `reusedConnections` which never appeared in actual Router REST API responses. Replaced with `stashedServerConnections` to match the real API response shape (`idleServerConnections` + `stashedServerConnections`)
60
- - **`safeRouterFetch` Stale JSDoc** — Docstring referenced `{ available: false, reason }` but implementation uses `{ available: false, error }` (corrected during the earlier `reason` → `error` normalization)
61
- - **Router Tool Catch-Block Error Shape Consistency** — 7 parameterized router handlers (`route_status`, `route_health`, `route_connections`, `route_destinations`, `route_blocked_hosts`, `metadata_status`, `pool_status`) had a defense-in-depth catch branch returning `{ available: false, error }` for unexpected non-Zod exceptions, inconsistent with the `{ success: false, error }` convention used by all other tool groups. Changed to `{ success: false, error }`. The `{ available: false }` shape is now reserved exclusively for `safeRouterFetch` connectivity failures
62
-
63
- ### Improved
64
-
65
27
  - **ServerInstructions Router Error Documentation** — Updated unavailability handling documentation to describe both error shapes: `{ available: false, error }` for connectivity failures and `{ success: false, error }` for 404 (nonexistent route/metadata/pool)
66
28
 
67
- ### Fixed
68
-
69
- - **ProxySQL Split Schema Validation Leaks** — 5 ProxySQL tools (`proxysql_servers`, `proxysql_connection_pool`, `proxysql_query_rules`, `proxysql_query_digest`, `proxysql_global_variables`) used strict Zod schemas as `inputSchema`, causing the MCP framework to reject invalid inputs (negative `hostgroup_id`, negative/float `limit`) with raw `-32602` errors before the handler's `try/catch` could format them. Applied Split Schema pattern: permissive Base schemas for MCP framework visibility, strict schemas for handler-level parsing. All validation failures now return `{ success: false, error }` structured responses
70
- - **Router Tool Error Field Normalization (`reason` → `error`)** — All 9 router tools returned `{ available: false, reason }` for unavailability/error responses, violating the convention where `reason` is reserved for informational `{ success: true, skipped: true }` contexts. Renamed to `{ available: false, error }` for consistency with all other tool groups
71
- - **Router Tool Zod Validation Leaks (7 Handlers)** — `mysql_router_route_status`, `mysql_router_route_health`, `mysql_router_route_connections`, `mysql_router_route_destinations`, `mysql_router_route_blocked_hosts`, `mysql_router_metadata_status`, and `mysql_router_pool_status` called `Schema.parse(params)` outside their `try/catch` blocks, causing raw Zod validation errors to propagate as MCP exceptions when invalid parameter types were passed (e.g., `routeName: 123`). Moved all `parse()` calls inside `try/catch` with `ZodError` detection and human-readable error formatting, matching the pattern used by all other tool groups
72
-
73
- ### Security
74
-
75
- - **ProxySQL Numeric Interpolation Hardening** — Added `Math.max(0, Math.floor())` defense-in-depth for all 5 SQL-interpolated numeric parameters (`hostgroup_id`, `limit`) across `proxysql_servers`, `proxysql_connection_pool`, `proxysql_query_rules`, `proxysql_query_digest`, and `proxysql_global_variables`. Zod validates first, but coercion prevents any bypass from reaching SQL
76
- - **ProxySQL `like` Pattern Validation** — `proxysql_global_variables` `like` parameter previously only applied single-quote escaping, leaving a potential SQL injection surface. Added `LIKE_SAFE_RE` regex validation that rejects patterns containing characters outside `[a-zA-Z0-9_%\-. *]` with a structured error before any SQL interpolation
77
-
78
- ### Improved
79
-
80
29
  - **ProxySQL `formatZodError` Consistency** — Replaced inline `error.issues.map(i => i.message).join("; ")` in all 11 ProxySQL handler catch blocks with centralized `formatZodError()` helper, matching the pattern used across all other tool groups
81
30
  - **ServerInstructions ProxySQL Documentation** — Documented `like` pattern safe character set validation, `hostgroup_id` non-negative integer constraint, and `limit` non-negative integer constraint for query analysis tools
82
31
 
83
- ### Fixed
84
-
85
- - **Redundant `proxysql_hostgroups` Tool Removed** — `proxysql_hostgroups` and `proxysql_connection_pool` both queried `SELECT * FROM stats_mysql_connection_pool` with identical response shapes, making `proxysql_hostgroups` completely redundant. Removed `proxysql_hostgroups` — use `proxysql_connection_pool` (which supports `hostgroup_id` filtering) instead. ProxySQL tool count: 12 → 11, total tools: 193 → 192
86
- - **ProxySQL `hostgroup_id` Negative Value Acceptance** — `ProxySQLHostgroupInputSchema` used `z.number().int().optional()` without `.nonnegative()`, allowing negative `hostgroup_id` values (e.g., `-1`) to silently return empty results. Added `.nonnegative()` so negative values are rejected at the Zod validation level with structured `{ success: false, error }` responses
87
-
88
- ### Improved
89
-
90
32
  - **ServerInstructions ProxySQL Documentation** — Updated backend servers documentation to reflect removal of `proxysql_hostgroups` and document that `hostgroup_id` must be a non-negative integer
91
33
 
92
34
  - **ProxySQL `limit` Float and Negative Acceptance** — `ProxySQLLimitInputSchema` and `ProxySQLVariableFilterSchema` used `z.number().optional()` without `.int()` or `.min(0)`, allowing float values (e.g., `1.5`) and negative limits (e.g., `-5`) to pass validation and be interpolated into SQL. Added `.int().min(0)` to both schemas so non-integer and negative limits are rejected at the Zod validation level with structured error responses
93
35
  - **ProxySQL `hostgroup_id` Float Acceptance** — `ProxySQLHostgroupInputSchema` used `z.number().optional()` without `.int()`, allowing float values like `1.5` to be interpolated into SQL `WHERE hostgroup_id = 1.5`. Added `.int()` so non-integer hostgroup IDs are rejected at validation
94
36
 
95
- ### Improved
96
-
97
37
  - **ServerInstructions ProxySQL Error Documentation** — Updated ProxySQL error handling documentation from "propagate connection errors" to document that all 12 tools return `{ success: false, error }` for connection failures, query errors, and invalid parameters. Added `hostgroup_id` integer-only and `limit` non-negative integer constraints
98
38
 
99
39
  - **`mysql_cluster_instances` Prepared Statement Incompatibility** — Both the primary InnoDB Cluster metadata query and the Group Replication fallback query used `LIMIT ?` parameterized placeholders, which are incompatible with `performance_schema` and `mysql_innodb_cluster_metadata` tables in the `mysql2` prepared statement protocol (`Incorrect arguments to mysqld_stmt_execute`). Changed to string-interpolated `LIMIT ${String(limit)}` (safe: value is Zod-validated as `z.number().int().min(0)`), matching the pattern used by `mysql_security_audit` for `performance_schema` queries
100
40
  - **`mysql_cluster_instances` Fallback Error Context Lost** — When the primary InnoDB Cluster metadata query fails and the GR fallback query also fails, only the fallback error was returned, discarding the primary error (often the actual root cause). Now includes `primaryError` field in the error response for complete diagnostic context
101
41
 
102
- ### Improved
103
-
104
42
  - **ServerInstructions Cluster Instances Documentation** — Documented `mysql_cluster_instances` fallback behavior from InnoDB Cluster metadata to Group Replication member data, and the `source: "group_replication"` field present in fallback responses
105
43
 
106
- ### Security
107
-
108
- - **`mysql_doc_find` Filter SQL Injection Fix** — The `filter` parameter was interpolated directly into the SQL query (`WHERE JSON_EXTRACT(doc, '${filter}') IS NOT NULL`), allowing arbitrary SQL injection via crafted filter values (e.g., `$') IS NOT NULL OR 1=1 -- `). Added `JSON_PATH_RE` validation regex that rejects any filter containing characters outside the valid JSON path set (`$`, `.`, `[`, `]`, `*`, alphanumeric, underscore). Invalid paths now return `{ success: false, error: "Invalid JSON path filter: ..." }` instead of executing
109
- - **`parseDocFilter` Field Name Validation Hardening** — Added explicit `IDENTIFIER_RE` validation for field names extracted from `field=value` filter patterns as defense-in-depth. While the existing regex already limited field names to identifier characters, the explicit check ensures future regex changes cannot introduce injection surfaces
110
-
111
- ### Improved
112
-
113
44
  - **Docstore Schema Parameter (5 Tools)** — `mysql_doc_add`, `mysql_doc_find`, `mysql_doc_modify`, `mysql_doc_remove`, and `mysql_doc_create_index` now accept an optional `schema` parameter for cross-database collection access. Previously these 5 tools hardcoded `DATABASE()` for collection existence checks and query execution, making collections created in non-default databases invisible. All 5 tools now pass `schema` to `checkCollectionExists()` and use `escapeTableRef()` for qualified table references (`` `schema`.`collection` ``)
114
45
  - **ServerInstructions Docstore Schema Documentation** — Updated docstore section to document the new `schema` parameter on all 5 tools, added `mysql_doc_collection_info` to the schema existence check documentation, and documented `mysql_doc_find` JSON path validation behavior
115
46
 
116
- ### Fixed
117
-
118
- - **`mysql_cluster_instances` Float Limit Acceptance** — `LimitSchema` used `z.number().min(0)` without `.int()`, allowing float values like `0.5` to pass Zod validation but cause a MySQL syntax error (`near '0.5'`). Added `.int()` constraint so non-integer limits are rejected with a structured error response
119
- - **`mysql_cluster_instances` Split Schema Violation** — `inputSchema` used the strict `LimitSchema` (with `.int().min(0)`) directly, causing the MCP framework to reject invalid values (e.g., `limit: -1`) with a raw `-32602` Zod error before the handler's `try/catch` could intercept. Created `LimitSchemaBase` (permissive `z.number().optional()`) for `inputSchema`, keeping the strict `LimitSchema` for handler-level parsing inside `try/catch`, matching the Dual-Schema pattern used across all other tool groups
120
- - **`mysql_cluster_switchover` `currentPrimary` Field Disappearing from JSON** — When no primary exists (GR offline), `members.find()` returns `undefined`, which JSON serialization silently drops — making the `currentPrimary` field absent from the response instead of explicitly `null`. Added `?? null` fallback so the field is always present. Also added `currentPrimary: null` to the error catch block so the field is present even on query failures
121
- - **`mysql_gr_flow_control` Inconsistent Error Shape** — The `gr_flow_control` catch block returned `{ success: false, error }` while all other 4 GR tools return domain-specific defaults with an `error` field (`{ enabled: false }`, `{ members: [], count: 0 }`, `{ hasPrimary: false }`, `{ memberStats: [], gtid: {...} }`). Changed to return `{ configuration: {}, memberQueues: [], isThrottling: false, error }` for consistency
122
-
123
- ### Improved
124
-
125
47
  - **ServerInstructions Cluster Documentation** — Updated `mysql_cluster_instances` documentation to clarify `limit` must be a non-negative integer (not just `min: 0`). Updated `mysql_cluster_switchover` to document that `currentPrimary` is `null` (not absent) when no primary exists
126
48
 
127
49
  - **`mysql_security_audit` Fallback Filter Gap** — `eventType` and `startTime` parameters were silently ignored in the `performance_schema` fallback branch (when `mysql.audit_log` table is unavailable). `eventType` now generates an `EVENT_NAME LIKE ?` condition. `startTime` is documented as inapplicable (performance_schema uses picosecond counters, not ISO timestamps) and a `filtersIgnored`/`note` field is included in the response when it cannot be applied
@@ -129,8 +51,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
129
51
  - **`mysql_security_audit` Performance Schema Query Column Mismatch** — The `performance_schema.events_statements_history` fallback query referenced `HOST` (nonexistent column) and `CURRENT_USER` (MySQL function returning current session user, not the statement's author), causing `Unknown column 'HOST'` errors. Fixed by JOINing with `performance_schema.threads` for `PROCESSLIST_USER`/`PROCESSLIST_HOST`, providing accurate per-statement user and host information
130
52
  - **`mysql_security_audit` Prepared Statement Incompatibility** — The `performance_schema` fallback query used parameterized `?` placeholders, but MySQL's `performance_schema` does not support prepared statements, causing `Incorrect arguments to mysqld_stmt_execute` errors. Converted to text-protocol query with safe string interpolation (values are Zod-validated or single-quote-escaped)
131
53
 
132
- ### Improved
133
-
134
54
  - **JSON Tool Split Schema Migration** — Migrated 9 JSON tools (`json_insert`, `json_replace`, `json_remove`, `json_array_append`, `json_get`, `json_update`, `json_normalize`, `json_stats`, `json_index_suggest`) from inline Zod schemas to the Dual-Schema pattern in `types.ts`. All 9 tools now support parameter aliases (`tableName`/`name` for `table`, `col` for `column`, `filter` for `where`), matching the 5 tools (`json_extract`, `json_set`, `json_contains`, `json_keys`, `json_search`) that already supported aliases
135
55
  - **`mysql_stats_histogram` Buckets Clamping Warning** — When `buckets > 1024` is requested with `update: true`, the tool now includes a `warning` field (e.g., `"Requested 2000 buckets; clamped to max 1024"`) on the response instead of silently clamping. Matches the warning pattern used by `mysql_create_index` for HASH→BTREE conversion
136
56
  - **`mysql_kill_query` Split Schema Consistency** — Added `KillQuerySchemaBase` to align with the Dual-Schema pattern used by all other admin tools. `inputSchema` now uses `KillQuerySchemaBase` (visible to MCP clients) while handler parsing continues to use `KillQuerySchema`. No functional change — ensures consistent architecture across the admin group
@@ -153,6 +73,47 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
153
73
 
154
74
  ### Fixed
155
75
 
76
+ - **No-Argument Prompts Zod Validation Error** — All 9 prompts without required arguments (`mysql_tool_index`, `mysql_setup_router`, `mysql_setup_proxysql`, `mysql_setup_shell`, `mysql_setup_events`, `mysql_sys_schema_guide`, `mysql_setup_spatial`, `mysql_setup_cluster`, `mysql_setup_docstore`) failed with `MCP error -32602: Invalid arguments ... expected object, received undefined` when invoked. Root cause: `DatabaseAdapter.registerPrompt()` always passed `argsSchema: {}` to the SDK even for no-argument prompts, which created `z.object({})` and rejected `undefined` input from clients. Fixed by passing `argsSchema: undefined` when `prompt.arguments` is empty
77
+
78
+ - **All Prompts with Arguments — Zod Validation Error** — All 10 prompts with arguments (`mysql_quick_schema`, `mysql_database_health_check`, `mysql_backup_strategy`, `mysql_index_tuning`, `mysql_setup_replication`, `mysql_query_builder`, `mysql_quick_query`, `mysql_schema_design`, `mysql_performance_analysis`, `mysql_migration`) failed with `MCP error -32602: Invalid arguments ... expected object, received undefined` when invoked without arguments. Root cause: `DatabaseAdapter.registerPrompt()` built a Zod schema whenever `prompt.arguments.length > 0`, and the SDK wrapped it into `z.object({...})` via `normalizeObjectSchema()`. Even with all fields marked `.optional()`, `z.object().safeParse(undefined)` always rejects `undefined` input — making field-level optionality irrelevant. Two previous fix attempts addressed field-level optionality (`.optional()`, handler-level validation) but not the schema-level rejection. Definitive fix: `argsSchema` is now always `undefined` for all prompts, so the SDK skips Zod validation entirely. Handler-level required-arg validation (already present) returns a helpful guide message when required arguments are missing
79
+
80
+ - **`mysql_doc_list_collections` False-Positive Collection Detection** — Detection query only checked for a `doc JSON` column without verifying `_id` column existence, causing any table with a `doc JSON` column (e.g., `test_json_docs`) to be listed as a document collection. Added `_id` column check via `JOIN` on `information_schema.COLUMNS`, matching the documented heuristic ("tables containing a `doc JSON` column with an `_id` field")
81
+
82
+ - **Docstore Schema Detection (7 Tools)** — `mysql_doc_find`, `mysql_doc_add`, `mysql_doc_modify`, `mysql_doc_remove`, `mysql_doc_create_index`, `mysql_doc_create_collection`, and `mysql_doc_drop_collection` incorrectly returned `{ exists: false, collection }` or leaked raw SQL errors when a nonexistent `schema` parameter was provided. Upgraded `checkCollectionExists` to a discriminated return type that distinguishes schema-not-found from collection-not-found, added `ER_BAD_DB_ERROR` catch to `create_collection`, and added schema pre-check to `drop_collection`. All 7 tools now consistently return `{ exists: false, schema }` for nonexistent schemas, matching the P154 pattern
83
+ - **Security Tool Error-Field Consistency (3 Handlers)** — Three security tool error paths (`mysql_security_audit` access-denied, `mysql_security_firewall_status` plugin check failure, `mysql_security_firewall_rules` table access error) returned `{ success: false, message }` without the standard `error` field, making them inconsistent with the `{ success: false, error }` convention used across all other tools. Added `error` field to all three responses (keeping `message` for backward compatibility)
84
+ - **Security Tool Redundant `message` Field Removal (3 Handlers)** — Three security tool error paths (`mysql_security_audit` access-denied, `mysql_security_firewall_status` plugin check failure, `mysql_security_firewall_rules` table access error) returned both `error` and `message` fields with identical or redundant content. Removed the `message` field from all three, standardizing on the `error` field exclusively for `{ success: false }` responses
85
+ - **`mysql_security_ssl_status` Empty Cipher Default** — The `str()` helper in `encryption.ts` treated empty strings as valid, so `currentCipher` returned `""` instead of `"None"` when SSL was disabled (MySQL returns `Ssl_cipher: ""`). Changed `str()` to treat empty strings as absent, activating the `"None"` default. Same fix applies to `sslVersion` (`"N/A"` default) and `requireSecureTransport` (`"OFF"` default)
86
+ - **Security Tool Catch-Block Error Shape Consistency** — Three catch blocks in `audit.ts` returned domain-specific shapes (`{ available: false }`, `{ installed: false }`) without `success: false`, making them inconsistent with the `{ success: false, error }` convention used across all other tools. Added `success: false` to `mysql_security_audit` (audit-related errors), `mysql_security_firewall_rules` (table access errors), and `mysql_security_firewall_status` (plugin check failures)
87
+
88
+ - **Schema Tool Zod Validation Leaks (6 Handlers)** — All 6 schema handler files (`constraints.ts`, `scheduled_events.ts`, `views.ts`, `management.ts`, `routines.ts`, `triggers.ts`) called `Schema.parse(params)` outside any `try/catch` block, causing raw Zod validation errors to propagate as MCP exceptions. Additionally, `list_constraints` (`type`), `list_events` (`status`), and `create_view` (`algorithm`, `checkOption`) used `z.enum()` directly on their `inputSchema`, causing the MCP framework to reject invalid values with raw `-32602` errors before handlers could intercept. Applied Split Schema pattern: created permissive `*Base` schemas with `z.string()` for `inputSchema` visibility, kept strict `z.enum()` schemas for handler-level parsing inside `try/catch` with `ZodError` detection and `formatZodError()` formatting, matching the Dual-Schema pattern used by admin, backup, and other tool groups
89
+ - **`mysql_check_table` Zod Enum Validation Leak** — The `option` parameter used `z.enum()` on `CheckTableSchemaBase`, causing invalid option values (e.g., `"INVALID_OPTION"`) to be rejected at the MCP framework level with a raw `-32602` Zod validation error before the handler's `try/catch` could intercept. Widened to `z.string()` on the Base schema while keeping `z.enum()` on the handler-parsed `CheckTableSchema`, so invalid values are caught inside `try/catch` and returned as `{ success: false, error }`
90
+ - **`mysql_binlog_events` Negative Limit Acceptance** — `BinlogEventsSchema` used `z.number().optional()` without `.nonnegative()`, allowing negative `limit` values (e.g., `-1`) to pass Zod validation and be string-interpolated into SQL via `LIMIT ${limit}`, producing a raw MySQL syntax error. Added `.nonnegative()` so negative values are rejected at the Zod validation level with structured `{ success: false, error }` responses
91
+ - **`mysql_binlog_events` Zod Parse Outside `try/catch` / Split Schema Violation** — `BinlogEventsSchema.parse(params)` was called outside the handler's `try/catch` block, and the same strict schema was used as `inputSchema`, causing Zod validation errors to propagate as raw MCP `-32602` exceptions. Applied Split Schema pattern: created permissive `BinlogEventsSchemaBase` for `inputSchema` visibility, kept strict `BinlogEventsSchema` (with `.nonnegative()`) for handler parsing inside a new outer `try/catch` with `ZodError` detection and human-readable error formatting
92
+
93
+ - **`mysql_flush_tables` Missing `error` Field on Nonexistent Tables** — When called with nonexistent tables, the response returned `{ success: false, notFound, flushed }` without the standard `error` field required by the error consistency convention. Added `error: "Tables not found: ..."` to the response, matching the `{ success: false, error }` pattern used by all other tools. The `notFound` and `flushed` arrays remain as additional context
94
+
95
+ - **`mysql_json_index_suggest` DDL for Qualified Table Names** — Generated `indexDdl` wrapped qualified table names in a single backtick pair (`` `schema.table` ``) instead of properly escaping each part (`` `schema`.`table` ``), producing invalid MySQL syntax. The index name also included the schema prefix (e.g., `idx_schema.table_key`), which is invalid as an unquoted identifier. Fixed by using `escapeQualifiedTable()` for the `ALTER TABLE` clause and extracting just the table basename for the index name
96
+ - **Transaction Tool Zod Validation Leaks (`mysql_transaction_begin`, `mysql_transaction_execute`)** — Both tools used `z.enum()` for their `isolationLevel` parameter, and called Zod's `parse()` outside their `try/catch` blocks (or lacked `try/catch` entirely). This caused invalid enum values to be rejected with raw `-32602` errors before the handler could intercept them. Applied Split Schema pattern with widened `z.string()` base schemas, moved `parse()` inside `try/catch`, and returned structured `{ success: false, error }` responses for validation failures.
97
+ - **Core Tool Zod Validation Leaks (8 Tools)** — `mysql_read_query`, `mysql_write_query`, `mysql_list_tables`, `mysql_describe_table`, `mysql_create_table`, `mysql_drop_table`, `mysql_get_indexes`, and `mysql_create_index` called `Schema.parse(params)` outside their `try/catch` blocks, causing raw Zod validation errors to propagate as MCP exceptions when missing required parameters or invalid types were passed. Moved all `parse()` calls inside `try/catch` with `ZodError` detection and human-readable error formatting, matching the pattern used by all other tool groups.
98
+ - **`mysql_drop_table` Default Behavior** — The `ifExists` parameter in `DropTableSchemaBase` defaulted to `true`, contradicting the documented behavior and generic SQL defaults where it should be false unless explicitly requested. Changed the default value to `false`.
99
+
100
+ - **Router 404 Response Differentiation** — All 9 router tools returned `{ available: false, error }` for both "Router is down" (ECONNREFUSED, timeout, TLS, 401/500) and "route/metadata/pool not found" (404) scenarios, making them indistinguishable. `routerFetch` now attaches `statusCode` to thrown errors and `safeRouterFetch` detects 404 responses, returning `{ success: false, error }` (standard error convention) instead of `{ available: false }` (reserved for actual connectivity failures)
101
+ - **`ConnectionPoolStatusSchema` Field Mismatch** — Schema defined `reusedConnections` which never appeared in actual Router REST API responses. Replaced with `stashedServerConnections` to match the real API response shape (`idleServerConnections` + `stashedServerConnections`)
102
+ - **`safeRouterFetch` Stale JSDoc** — Docstring referenced `{ available: false, reason }` but implementation uses `{ available: false, error }` (corrected during the earlier `reason` → `error` normalization)
103
+ - **Router Tool Catch-Block Error Shape Consistency** — 7 parameterized router handlers (`route_status`, `route_health`, `route_connections`, `route_destinations`, `route_blocked_hosts`, `metadata_status`, `pool_status`) had a defense-in-depth catch branch returning `{ available: false, error }` for unexpected non-Zod exceptions, inconsistent with the `{ success: false, error }` convention used by all other tool groups. Changed to `{ success: false, error }`. The `{ available: false }` shape is now reserved exclusively for `safeRouterFetch` connectivity failures
104
+
105
+ - **ProxySQL Split Schema Validation Leaks** — 5 ProxySQL tools (`proxysql_servers`, `proxysql_connection_pool`, `proxysql_query_rules`, `proxysql_query_digest`, `proxysql_global_variables`) used strict Zod schemas as `inputSchema`, causing the MCP framework to reject invalid inputs (negative `hostgroup_id`, negative/float `limit`) with raw `-32602` errors before the handler's `try/catch` could format them. Applied Split Schema pattern: permissive Base schemas for MCP framework visibility, strict schemas for handler-level parsing. All validation failures now return `{ success: false, error }` structured responses
106
+ - **Router Tool Error Field Normalization (`reason` → `error`)** — All 9 router tools returned `{ available: false, reason }` for unavailability/error responses, violating the convention where `reason` is reserved for informational `{ success: true, skipped: true }` contexts. Renamed to `{ available: false, error }` for consistency with all other tool groups
107
+ - **Router Tool Zod Validation Leaks (7 Handlers)** — `mysql_router_route_status`, `mysql_router_route_health`, `mysql_router_route_connections`, `mysql_router_route_destinations`, `mysql_router_route_blocked_hosts`, `mysql_router_metadata_status`, and `mysql_router_pool_status` called `Schema.parse(params)` outside their `try/catch` blocks, causing raw Zod validation errors to propagate as MCP exceptions when invalid parameter types were passed (e.g., `routeName: 123`). Moved all `parse()` calls inside `try/catch` with `ZodError` detection and human-readable error formatting, matching the pattern used by all other tool groups
108
+
109
+ - **Redundant `proxysql_hostgroups` Tool Removed** — `proxysql_hostgroups` and `proxysql_connection_pool` both queried `SELECT * FROM stats_mysql_connection_pool` with identical response shapes, making `proxysql_hostgroups` completely redundant. Removed `proxysql_hostgroups` — use `proxysql_connection_pool` (which supports `hostgroup_id` filtering) instead. ProxySQL tool count: 12 → 11, total tools: 193 → 192
110
+ - **ProxySQL `hostgroup_id` Negative Value Acceptance** — `ProxySQLHostgroupInputSchema` used `z.number().int().optional()` without `.nonnegative()`, allowing negative `hostgroup_id` values (e.g., `-1`) to silently return empty results. Added `.nonnegative()` so negative values are rejected at the Zod validation level with structured `{ success: false, error }` responses
111
+
112
+ - **`mysql_cluster_instances` Float Limit Acceptance** — `LimitSchema` used `z.number().min(0)` without `.int()`, allowing float values like `0.5` to pass Zod validation but cause a MySQL syntax error (`near '0.5'`). Added `.int()` constraint so non-integer limits are rejected with a structured error response
113
+ - **`mysql_cluster_instances` Split Schema Violation** — `inputSchema` used the strict `LimitSchema` (with `.int().min(0)`) directly, causing the MCP framework to reject invalid values (e.g., `limit: -1`) with a raw `-32602` Zod error before the handler's `try/catch` could intercept. Created `LimitSchemaBase` (permissive `z.number().optional()`) for `inputSchema`, keeping the strict `LimitSchema` for handler-level parsing inside `try/catch`, matching the Dual-Schema pattern used across all other tool groups
114
+ - **`mysql_cluster_switchover` `currentPrimary` Field Disappearing from JSON** — When no primary exists (GR offline), `members.find()` returns `undefined`, which JSON serialization silently drops — making the `currentPrimary` field absent from the response instead of explicitly `null`. Added `?? null` fallback so the field is always present. Also added `currentPrimary: null` to the error catch block so the field is present even on query failures
115
+ - **`mysql_gr_flow_control` Inconsistent Error Shape** — The `gr_flow_control` catch block returned `{ success: false, error }` while all other 4 GR tools return domain-specific defaults with an `error` field (`{ enabled: false }`, `{ members: [], count: 0 }`, `{ hasPrimary: false }`, `{ memberStats: [], gtid: {...} }`). Changed to return `{ configuration: {}, memberQueues: [], isThrottling: false, error }` for consistency
116
+
156
117
  - **Cluster Tool Zod Validation Leaks (3 Tools)** — `mysql_cluster_status`, `mysql_cluster_instances`, and `mysql_cluster_router_status` called `Schema.parse(params)` outside their `try/catch` blocks, causing raw Zod validation errors to propagate as MCP exceptions when invalid parameter types were passed (e.g., `summary: "yes"`, `limit: "abc"`). Moved all `parse()` calls inside `try/catch` with `ZodError` detection and human-readable error formatting, matching the pattern used by admin and backup tools
157
118
  - **`mysql_cluster_instances` Negative Limit Guard** — Added `.min(0)` to `LimitSchema.limit` to reject negative values at the Zod validation level. Previously, `limit: -5` passed Zod validation but was string-interpolated into SQL via `LIMIT ${String(limit)}`, producing a raw MySQL syntax error
158
119
  - **`mysql_cluster_instances` Fallback Error Swallowing** — When the primary InnoDB Cluster metadata query fails, the handler falls back to a GR-only query. Previously, the fallback query was not wrapped in its own `try/catch`, so if both the primary and fallback queries failed, the fallback error would propagate as a raw MCP exception. Now wrapped in nested `try/catch` returning `{ instances: [], count: 0, error }` for complete error containment
@@ -249,6 +210,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
249
210
  - **Roles Tool Error Field Normalization (`reason` → `error`)** — `mysql_role_create`, `mysql_role_drop`, and `mysql_role_revoke` returned `{ success: false, reason }` for error conditions (duplicate role, nonexistent role, role not assigned), violating the convention where `reason` is reserved for informational `{ success: true, skipped: true }` responses. Changed all 3 occurrences to `{ success: false, error }` for consistency with all other tools. Updated ServerInstructions to match
250
211
  - **Roles Tool `validateIdentifier` Entity Label** — `mysql_role_grants`, `mysql_role_assign`, and `mysql_role_revoke` used `validateIdentifier(role, "column")`, producing misleading `"Invalid column name: ..."` error messages when role identifier validation failed. Changed entity label to `"role"` for accurate `"Invalid role name: ..."` messages
251
212
 
213
+ ### Security
214
+
215
+ - **Worker Sandbox API Bridge (Critical)** — The `CODEMODE_ISOLATION=worker` mode spawned a Worker thread but the `mysql.*` API bindings were non-functional — `serializeBindings()` stripped all functions to method name arrays, and `worker-script.ts` set `mysql: {}` (empty object). Implemented a `MessagePort`-based RPC bridge: the main thread listens on `port1` for `{ id, group, method, args }` requests and dispatches to real `MySQLAdapter` methods; the worker builds async proxy stubs via `buildMysqlProxy()` that send RPC requests through `port2` and await responses. Changed default sandbox mode from `vm` to `worker` for stronger V8 isolate separation. Readonly enforcement, `resourceLimits` memory caps, and timeout mechanisms remain fully functional
216
+
217
+ - **Code Mode Readonly Enforcement (Critical)** — The `readonly: true` flag on `mysql_execute_code` was accepted but never enforced — write tools (`writeQuery`, `dropTable`, `createTable`, `createIndex`) executed normally. Readonly mode now replaces write-oriented tool groups (`transactions`, `admin`, `backup`, `partitioning`, `roles`, `events`, `shell`) with stubs returning `{ success: false, error }`, and blocks individual write methods in mixed groups (`core`, `docstore`, `schema`, `json`, `fulltext`, `spatial`) with descriptive error messages
218
+ - **Worker Memory Limits Enforced (Critical)** — `WorkerSandbox` now passes `resourceLimits` (`maxOldGenerationSizeMb`, `maxYoungGenerationSizeMb`) to the `Worker` constructor, enforcing V8 heap limits. Previously, `memoryLimitMb` in sandbox options was accepted but ignored
219
+ - **Core Tool Group Scope Mapping (High)** — Fixed `core` tool group OAuth scope from `READ` → `WRITE`. The `core` group contains `writeQuery`, `dropTable`, `createTable`, and `createIndex`, which are write/DDL operations. A `READ`-scoped OAuth client could previously execute arbitrary write operations through `core` tools
220
+ - **HTTP Security Headers (Medium)** — Added `Strict-Transport-Security` (2-year max-age), `Referrer-Policy` (no-referrer), and `Permissions-Policy` (camera/microphone/geolocation denied) to all HTTP transport responses, complementing existing CSP, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, and Cache-Control headers
221
+ - **Sandbox Blocked Pattern Hardening (Medium)** — Added detection for bracket-notation constructor access (`['constructor']`) and `Reflect.construct` bypass vectors, closing two confirmed regex blocklist gaps in Code Mode security validation
222
+
223
+ - **ProxySQL Numeric Interpolation Hardening** — Added `Math.max(0, Math.floor())` defense-in-depth for all 5 SQL-interpolated numeric parameters (`hostgroup_id`, `limit`) across `proxysql_servers`, `proxysql_connection_pool`, `proxysql_query_rules`, `proxysql_query_digest`, and `proxysql_global_variables`. Zod validates first, but coercion prevents any bypass from reaching SQL
224
+ - **ProxySQL `like` Pattern Validation** — `proxysql_global_variables` `like` parameter previously only applied single-quote escaping, leaving a potential SQL injection surface. Added `LIKE_SAFE_RE` regex validation that rejects patterns containing characters outside `[a-zA-Z0-9_%\-. *]` with a structured error before any SQL interpolation
225
+
226
+ - **`mysql_doc_find` Filter SQL Injection Fix** — The `filter` parameter was interpolated directly into the SQL query (`WHERE JSON_EXTRACT(doc, '${filter}') IS NOT NULL`), allowing arbitrary SQL injection via crafted filter values (e.g., `$') IS NOT NULL OR 1=1 -- `). Added `JSON_PATH_RE` validation regex that rejects any filter containing characters outside the valid JSON path set (`$`, `.`, `[`, `]`, `*`, alphanumeric, underscore). Invalid paths now return `{ success: false, error: "Invalid JSON path filter: ..." }` instead of executing
227
+ - **`parseDocFilter` Field Name Validation Hardening** — Added explicit `IDENTIFIER_RE` validation for field names extracted from `field=value` filter patterns as defense-in-depth. While the existing regex already limited field names to identifier characters, the explicit check ensures future regex changes cannot introduce injection surfaces
228
+
229
+ - **CVE Fix: `hono` Timing Comparison Hardening (GHSA-gq3j-xvxp-8hrf)** — Updated transitive dependency `hono` to ≥4.11.10 via `npm audit fix` to add timing comparison hardening in `basicAuth` and `bearerAuth` middleware, preventing timing-based credential leakage
230
+ - **CVE Fix: `rollup` Arbitrary File Write via Path Traversal (GHSA-mw96-cpmx-2vgc)** — Updated transitive dependency `rollup` (via `vitest` → `vite`) from <4.58.1 to 4.59.0 via `npm audit fix` to fix a high-severity arbitrary file write vulnerability through path traversal in generated bundle output
231
+
252
232
  ### Infrastructure
253
233
 
254
234
  - **`.gitattributes` Line Ending Normalization** — Added `.gitattributes` to enforce LF line endings in the repository (`* text=auto eol=lf`), with explicit CRLF exceptions for Windows-only scripts (`.ps1`, `.cmd`, `.bat`). Prevents cross-platform line ending corruption from contributors with differing `core.autocrlf` settings
@@ -258,11 +238,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
258
238
 
259
239
  - **README.md / DOCKER_README.md "Deterministic Error Handling"** — Added "deterministic error handling" to the introduction blurbs and a new "Deterministic Error Handling" row to the "What Sets Us Apart" feature table in both READMEs, highlighting structured `{success, error}` responses across all tools
260
240
 
261
- ### Security
262
-
263
- - **CVE Fix: `hono` Timing Comparison Hardening (GHSA-gq3j-xvxp-8hrf)** — Updated transitive dependency `hono` to ≥4.11.10 via `npm audit fix` to add timing comparison hardening in `basicAuth` and `bearerAuth` middleware, preventing timing-based credential leakage
264
- - **CVE Fix: `rollup` Arbitrary File Write via Path Traversal (GHSA-mw96-cpmx-2vgc)** — Updated transitive dependency `rollup` (via `vitest` → `vite`) from <4.58.1 to 4.59.0 via `npm audit fix` to fix a high-severity arbitrary file write vulnerability through path traversal in generated bundle output
265
-
266
241
  ### Changed
267
242
 
268
243
  - **`mysql2` 3.18.0 Type Compatibility** — Adjusted `MySQLAdapter.executeOnConnection()` and `ConnectionPool.execute()` to satisfy mysql2 3.18.0's stricter `QueryValues` type constraint on `execute()` and `query()` parameter signatures
@@ -621,6 +596,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
621
596
  - **MySQL Shell Tools Error Handling** — Improved error detection in `execShellJS()` to properly catch errors from stderr (e.g., `local_infile disabled`, privilege errors, fatal dump errors) instead of silently returning raw output.
622
597
  - **MySQL Shell Export Table** — Removed unsupported `columns` option from `mysqlsh_export_table` (not supported by `util.exportTable()` in MySQL Shell 9.x).
623
598
 
599
+ - Removed unused imports and variables from 9 test files to improve code quality (CodeQL alerts #8-18)
600
+ - **ProxySQL Runtime Status** - Fixed `proxysql_runtime_status` failing with SQL syntax error "near 'version': syntax error". The tool was using `@@admin-version` syntax which is not supported by ProxySQL's SQLite-based admin interface. Now correctly queries `global_variables` table.
601
+ - **CRITICAL: MCP stdio Transport Crash** - Removed debug `console.error` in `MySQLAdapter.executeOnConnection()` that was writing to stderr and corrupting the MCP stdio JSON-RPC message stream, causing the server to crash when any tool was called. This was introduced during the DDL support improvements.
602
+ - **DDL Support** - Fixed `mysql_write_query` failing on DDL statements (like `CREATE TABLE`, `CREATE USER`) by implementing automatic fallback to the text protocol when the specific "not supported in prepared statement protocol" error is encountered.
603
+ - **JSON Validation** - Enforced strict JSON validation for `mysql_json_*` tools. String values must now be properly quoted (e.g., `'"value"'`) to be stored as strings. Unquoted strings that are invalid JSON will now throw a descriptive error instead of being accepted and potentially mishandled.
604
+ - **JSON & Text Tools Qualified Table Names** - Fixed all 17 JSON tools and 6 text processing tools to correctly handle schema-qualified table names (e.g., `schema.table`). Previously these tools would reject qualified names with "Invalid table name" errors. Now uses `validateQualifiedIdentifier()` and `escapeQualifiedTable()` for proper handling.
605
+ - Fixed potential issue in `indexes` resource where undefined query results could lead to undefined properties instead of empty arrays.
606
+ - Fixed SQL syntax errors in `mysql_stats_descriptive` tool: escaped `range` reserved keyword and fixed invalid LIMIT/OFFSET syntax in median calculation.
607
+ - Fixed `mysql_json_index_suggest` compatibility with `ONLY_FULL_GROUP_BY` and corrected sampling logic.
608
+ - Fixed `mysql_spatial_polygon` schema validation error by replacing `z.tuple` with `z.array` to generate compatible JSON schema.
609
+ - **Spatial SRID Fix** - Fixed `mysql_spatial_contains` and `mysql_spatial_within` failing on columns with SRID 4326 due to SRID mismatch. Both tools now accept an optional `srid` parameter (default: 4326) and wrap input geometries with `ST_SRID()` to match the column's SRID.
610
+ - **Spatial Coordinate Order** - Fixed `mysql_spatial_point`, `mysql_spatial_distance`, and `mysql_spatial_distance_sphere` creating POINT geometries with incorrect coordinate order for SRID 4326. MySQL 8.0+ follows the EPSG standard axis order (latitude, longitude) for SRID 4326, but the tools were generating `POINT(longitude latitude)`. Now correctly generates `POINT(latitude longitude)`. Updated `mysql_setup_spatial` prompt documentation accordingly.
611
+ - Improved branch coverage across multiple modules.
612
+ - Fixed `mysql_sys_io_summary` failing on MySQL 9.4 due to schema changes in `sys.io_global_by_wait_by_latency` (replaced `wait_class` with `event_name`).
613
+ - **Table Name Handling** - Fixed `mysql_create_table`, `mysql_drop_table`, `mysql_create_index`, `mysql_describe_table`, and `mysql_get_indexes` to correctly handle fully qualified table names (e.g., `schema.table`). Added intelligent parsing and proper backtick escaping for schema prefixes.
614
+ - **Role Grant Handling** - Fixed `mysql_role_grant` to correctly handle schema-qualified table names (e.g., `schema.table`) in the `table` parameter, preventing syntax errors when specifying target tables.
615
+ - **Fixed Role Grant** - Fixed `mysql_role_grant` tool logic to correctly handle wildcard privileges (`*`) versus specific table grants, resolving syntax errors when granting privileges to specific tables.
616
+ - **Schema-Qualified CREATE TABLE** - Fixed `mysql_create_table` failing with "No database selected" when using schema-qualified names (e.g., `testdb.table`). Now automatically issues `USE schema` before CREATE TABLE when a qualified name is detected.
617
+ - **View Management** - Fixed `mysql_create_view` to correctly handle schema-qualified view names (e.g. `schema.view`) and improved validation error messages.
618
+ - **Router TLS Self-Signed Certificates** - Fixed `mysql_router_*` tools failing with "fetch failed" when connecting to Router REST API using HTTPS with self-signed certificates. The `MYSQL_ROUTER_INSECURE=true` environment variable now properly bypasses certificate verification using a targeted HTTPS agent with `rejectUnauthorized: false`.
619
+
624
620
  ### Removed
625
621
 
626
622
  - **Jupyter Quickstart Notebook** — Removed `examples/notebooks/quickstart.ipynb` and the `examples/` directory. The notebook had kernel instability issues on Windows (ZMQ socket errors causing kernel restarts during MCP subprocess communication). Usage instructions are now provided to AI agents automatically via the MCP protocol's `instructions` capability.
@@ -629,21 +625,47 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
629
625
 
630
626
  - **Server Instructions** — Added document store filter syntax documentation with examples for `mysql_doc_modify` and `mysql_doc_remove`. Added spatial tools section documenting coordinate order behavior and MySQL 8.0+ EPSG standard handling with `axis-order=long-lat` option.
631
627
 
628
+ - **Partitioning Schema Descriptions** — Improved `value` parameter descriptions in `AddPartitionSchema` and `ReorganizePartitionSchema` to clarify that only boundary values should be provided (e.g., `"2024"`), not full SQL clauses (e.g., `"LESS THAN (2024)"`).
629
+ - **Server Instructions** — Added partitioning tools section with usage guidance and examples to prevent common parameter format errors.
630
+
631
+ - **Logger Test Updates** — Updated logger tests to match RFC 5424 severity levels:
632
+ - `warn` → `warning` level naming
633
+ - Updated format assertions to match `[LEVEL]` structured format (e.g., `[WARNING]`, `[DEBUG]`)
634
+
632
635
  ### Added
633
636
 
634
637
  - **`mysqlsh_import_table` / `mysqlsh_load_dump` — `updateServerSettings` parameter** — New boolean option to automatically enable `local_infile` on the server before import/load operations. Requires SUPER or SYSTEM_VARIABLES_ADMIN privilege.
635
638
  - **`mysqlsh_dump_schemas` — `ddlOnly` parameter** — New boolean option to dump only DDL (schema structure) without events, triggers, or routines. Useful when the user lacks EVENT or TRIGGER privileges.
636
639
  - **`mysqlsh_dump_tables` — `all` parameter** — New boolean option (default: false) to control whether triggers are included in the dump. Set to `false` to skip triggers when lacking TRIGGER privilege.
637
640
 
638
- ### Changed
639
-
640
- - **Partitioning Schema Descriptions** — Improved `value` parameter descriptions in `AddPartitionSchema` and `ReorganizePartitionSchema` to clarify that only boundary values should be provided (e.g., `"2024"`), not full SQL clauses (e.g., `"LESS THAN (2024)"`).
641
- - **Server Instructions** — Added partitioning tools section with usage guidance and examples to prevent common parameter format errors.
642
-
643
- ### Added
644
-
645
641
  - **Server Instructions** — Usage instructions are now automatically provided to AI agents via the MCP protocol's `instructions` capability during server initialization. See [`src/constants/ServerInstructions.ts`](src/constants/ServerInstructions.ts).
646
642
 
643
+ - **SchemaManager Cache Tests** — Added tests for cache TTL expiration, cache invalidation, and schema-qualified table name handling in `getTableIndexes()`
644
+ - **Logger Coverage Improvements** — Added 30+ tests covering:
645
+ - `setLoggerName()`, `getLoggerName()`, `setDefaultModule()` configuration methods
646
+ - `notice()`, `critical()`, `alert()`, `emergency()` log levels
647
+ - `forModule()` module-scoped logger with all severity levels
648
+ - Code formatting in log output
649
+ - **CI/CD Quality Gate** - Added `quality-gate` job to `docker-publish.yml` workflow that runs lint, typecheck, and all 1478 unit tests before allowing Docker image builds. Deployments now require all tests to pass.
650
+ - Added comprehensive test coverage for `MySQLAdapter`, `TokenValidator`, and `comparative` stats tools.
651
+ - Added unit tests for security audit tool fallbacks and filtering logic.
652
+ - Added meaningful tests for `locks` resource to handle undefined/partial query results.
653
+ - Added test coverage for `indexes` resource edge cases (undefined rows).
654
+ - Added test coverage for `events` resource edge cases.
655
+ - Added meaningful test coverage for `constraints.ts` (schema-qualified table parsing), `router.ts` (auth headers, TLS handling), and `utilities.ts` (option handling branches).
656
+ - Added comprehensive tests for `security` tool edge cases (encryption status, SSL status).
657
+ - Added tests for `views` schema tool validation and check options.
658
+ - **Transaction-Aware Queries** - Added optional `transactionId` parameter to `mysql_read_query` and `mysql_write_query` tools, enabling interactive queries within active transactions.
659
+ - **MCP Enhanced Logging** — Full MCP protocol-compliant structured logging
660
+ - RFC 5424 severity levels: debug, info, notice, warning, error, critical, alert, emergency
661
+ - Module-prefixed error codes (e.g., `DB_CONNECT_FAILED`, `AUTH_TOKEN_INVALID`)
662
+ - Structured log format: `[timestamp] [LEVEL] [MODULE] [CODE] message {context}`
663
+ - Module-scoped loggers via `logger.forModule()` and `logger.child()`
664
+ - Sensitive data redaction for OAuth 2.1 configuration fields
665
+ - Stack trace inclusion for error-level logs with sanitization
666
+ - Log injection prevention via control character sanitization
667
+ - **All 191 tools and 26 resources fully tested** - Comprehensive testing completed including InnoDB Cluster (3-node Group Replication), MySQL Router REST API, ProxySQL admin interface, and MySQL Shell utilities.
668
+
647
669
  ### Testing
648
670
 
649
671
  - **Branch Coverage Improvements** — Added 112 new tests targeting uncovered branches across multiple modules:
@@ -678,40 +700,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
678
700
  - **MySQLAdapter Resource/Prompt Definition Caching** — Added `cachedResourceDefinitions` and `cachedPromptDefinitions` to match the existing `cachedToolDefinitions` pattern, avoiding re-invocation of 18 resource and 13 prompt factory functions.
679
701
  - **Core Tool Handler Hoisted Regex** — Moved inline regex patterns (`isValidId`, index name validation) to module-level pre-compiled constants in `core.ts`.
680
702
 
681
- ### Changed
682
-
683
- - **Logger Test Updates** — Updated logger tests to match RFC 5424 severity levels:
684
- - `warn` → `warning` level naming
685
- - Updated format assertions to match `[LEVEL]` structured format (e.g., `[WARNING]`, `[DEBUG]`)
686
-
687
- ### Added
688
-
689
- - **SchemaManager Cache Tests** — Added tests for cache TTL expiration, cache invalidation, and schema-qualified table name handling in `getTableIndexes()`
690
- - **Logger Coverage Improvements** — Added 30+ tests covering:
691
- - `setLoggerName()`, `getLoggerName()`, `setDefaultModule()` configuration methods
692
- - `notice()`, `critical()`, `alert()`, `emergency()` log levels
693
- - `forModule()` module-scoped logger with all severity levels
694
- - Code formatting in log output
695
- - **CI/CD Quality Gate** - Added `quality-gate` job to `docker-publish.yml` workflow that runs lint, typecheck, and all 1478 unit tests before allowing Docker image builds. Deployments now require all tests to pass.
696
- - Added comprehensive test coverage for `MySQLAdapter`, `TokenValidator`, and `comparative` stats tools.
697
- - Added unit tests for security audit tool fallbacks and filtering logic.
698
- - Added meaningful tests for `locks` resource to handle undefined/partial query results.
699
- - Added test coverage for `indexes` resource edge cases (undefined rows).
700
- - Added test coverage for `events` resource edge cases.
701
- - Added meaningful test coverage for `constraints.ts` (schema-qualified table parsing), `router.ts` (auth headers, TLS handling), and `utilities.ts` (option handling branches).
702
- - Added comprehensive tests for `security` tool edge cases (encryption status, SSL status).
703
- - Added tests for `views` schema tool validation and check options.
704
- - **Transaction-Aware Queries** - Added optional `transactionId` parameter to `mysql_read_query` and `mysql_write_query` tools, enabling interactive queries within active transactions.
705
- - **MCP Enhanced Logging** — Full MCP protocol-compliant structured logging
706
- - RFC 5424 severity levels: debug, info, notice, warning, error, critical, alert, emergency
707
- - Module-prefixed error codes (e.g., `DB_CONNECT_FAILED`, `AUTH_TOKEN_INVALID`)
708
- - Structured log format: `[timestamp] [LEVEL] [MODULE] [CODE] message {context}`
709
- - Module-scoped loggers via `logger.forModule()` and `logger.child()`
710
- - Sensitive data redaction for OAuth 2.1 configuration fields
711
- - Stack trace inclusion for error-level logs with sanitization
712
- - Log injection prevention via control character sanitization
713
- - **All 191 tools and 26 resources fully tested** - Comprehensive testing completed including InnoDB Cluster (3-node Group Replication), MySQL Router REST API, ProxySQL admin interface, and MySQL Shell utilities.
714
-
715
703
  ### Security
716
704
 
717
705
  - **CodeQL Remediation** - Fixed 4 security vulnerabilities identified by CodeQL analysis:
@@ -720,29 +708,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
720
708
  - Fixed incomplete string escaping in quick query prompt (now escapes backslashes before quotes)
721
709
  - **Router TLS Handling** - Replaced global `NODE_TLS_REJECT_UNAUTHORIZED` environment variable manipulation with a targeted HTTPS `Agent` for insecure mode. This eliminates the CodeQL "disabling certificate validation" alert while still supporting self-signed certificates for development/testing via the `MYSQL_ROUTER_INSECURE=true` option.
722
710
 
723
- ### Fixed
724
-
725
- - Removed unused imports and variables from 9 test files to improve code quality (CodeQL alerts #8-18)
726
- - **ProxySQL Runtime Status** - Fixed `proxysql_runtime_status` failing with SQL syntax error "near 'version': syntax error". The tool was using `@@admin-version` syntax which is not supported by ProxySQL's SQLite-based admin interface. Now correctly queries `global_variables` table.
727
- - **CRITICAL: MCP stdio Transport Crash** - Removed debug `console.error` in `MySQLAdapter.executeOnConnection()` that was writing to stderr and corrupting the MCP stdio JSON-RPC message stream, causing the server to crash when any tool was called. This was introduced during the DDL support improvements.
728
- - **DDL Support** - Fixed `mysql_write_query` failing on DDL statements (like `CREATE TABLE`, `CREATE USER`) by implementing automatic fallback to the text protocol when the specific "not supported in prepared statement protocol" error is encountered.
729
- - **JSON Validation** - Enforced strict JSON validation for `mysql_json_*` tools. String values must now be properly quoted (e.g., `'"value"'`) to be stored as strings. Unquoted strings that are invalid JSON will now throw a descriptive error instead of being accepted and potentially mishandled.
730
- - **JSON & Text Tools Qualified Table Names** - Fixed all 17 JSON tools and 6 text processing tools to correctly handle schema-qualified table names (e.g., `schema.table`). Previously these tools would reject qualified names with "Invalid table name" errors. Now uses `validateQualifiedIdentifier()` and `escapeQualifiedTable()` for proper handling.
731
- - Fixed potential issue in `indexes` resource where undefined query results could lead to undefined properties instead of empty arrays.
732
- - Fixed SQL syntax errors in `mysql_stats_descriptive` tool: escaped `range` reserved keyword and fixed invalid LIMIT/OFFSET syntax in median calculation.
733
- - Fixed `mysql_json_index_suggest` compatibility with `ONLY_FULL_GROUP_BY` and corrected sampling logic.
734
- - Fixed `mysql_spatial_polygon` schema validation error by replacing `z.tuple` with `z.array` to generate compatible JSON schema.
735
- - **Spatial SRID Fix** - Fixed `mysql_spatial_contains` and `mysql_spatial_within` failing on columns with SRID 4326 due to SRID mismatch. Both tools now accept an optional `srid` parameter (default: 4326) and wrap input geometries with `ST_SRID()` to match the column's SRID.
736
- - **Spatial Coordinate Order** - Fixed `mysql_spatial_point`, `mysql_spatial_distance`, and `mysql_spatial_distance_sphere` creating POINT geometries with incorrect coordinate order for SRID 4326. MySQL 8.0+ follows the EPSG standard axis order (latitude, longitude) for SRID 4326, but the tools were generating `POINT(longitude latitude)`. Now correctly generates `POINT(latitude longitude)`. Updated `mysql_setup_spatial` prompt documentation accordingly.
737
- - Improved branch coverage across multiple modules.
738
- - Fixed `mysql_sys_io_summary` failing on MySQL 9.4 due to schema changes in `sys.io_global_by_wait_by_latency` (replaced `wait_class` with `event_name`).
739
- - **Table Name Handling** - Fixed `mysql_create_table`, `mysql_drop_table`, `mysql_create_index`, `mysql_describe_table`, and `mysql_get_indexes` to correctly handle fully qualified table names (e.g., `schema.table`). Added intelligent parsing and proper backtick escaping for schema prefixes.
740
- - **Role Grant Handling** - Fixed `mysql_role_grant` to correctly handle schema-qualified table names (e.g., `schema.table`) in the `table` parameter, preventing syntax errors when specifying target tables.
741
- - **Fixed Role Grant** - Fixed `mysql_role_grant` tool logic to correctly handle wildcard privileges (`*`) versus specific table grants, resolving syntax errors when granting privileges to specific tables.
742
- - **Schema-Qualified CREATE TABLE** - Fixed `mysql_create_table` failing with "No database selected" when using schema-qualified names (e.g., `testdb.table`). Now automatically issues `USE schema` before CREATE TABLE when a qualified name is detected.
743
- - **View Management** - Fixed `mysql_create_view` to correctly handle schema-qualified view names (e.g. `schema.view`) and improved validation error messages.
744
- - **Router TLS Self-Signed Certificates** - Fixed `mysql_router_*` tools failing with "fetch failed" when connecting to Router REST API using HTTPS with self-signed certificates. The `MYSQL_ROUTER_INSECURE=true` environment variable now properly bypasses certificate verification using a targeted HTTPS agent with `rejectUnauthorized: false`.
745
-
746
711
  ### Coverage
747
712
 
748
713
  - Branch coverage: ~83.87%
@@ -796,16 +761,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
796
761
  - **Code Quality** - Removed all `eslint-disable` directives across the codebase, ensuring strict type safety and linting compliance.
797
762
  - **Test Coverage** - Improved coverage for `http.ts`, `logger.ts`, and `validators.ts` with meaningful test cases.
798
763
 
799
- ### Added
800
-
801
- - **Performance Test Suite** - Added `src/__tests__/perf.test.ts` with 11 timing-based tests for regression protection:
802
- - Tool definition caching validation for `MySQLAdapter.getToolDefinitions()`
803
- - O(1) lookup verification for `getToolGroup()` (Map vs linear search)
804
- - Caching validation for `getAllToolNames()` and `parseToolFilter()`
805
- - Filter performance tests for complex filter chains (-base,-ecosystem,+starter)
806
-
807
- ### Changed
808
-
809
764
  - **Code Organization - Modular Refactoring** - Improved code maintainability by refactoring large monolithic tool files (500+ lines) into focused, modular directory structures:
810
765
  - Phase 1 (Initial Refactoring):
811
766
  - `tools/spatial/` - Split 565-line file into 4 modules: `setup.ts`, `geometry.ts`, `queries.ts`, `operations.ts`
@@ -833,30 +788,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
833
788
  - **Cached Tool Names** - `getAllToolNames()` caches the 191-tool array after first computation
834
789
  - Added `clearToolFilterCaches()` export for testing purposes
835
790
 
836
- ### Fixed
791
+ - Tool groups increased from 15 to 24 (9 new groups)
792
+ - JSON tools increased from 12 to 17
793
+ - Updated meta-groups: `starter` (~45), `dev` (~65), `base` (~160)
794
+ - README updated with new tool groups and meta-groups
837
795
 
838
- - **Test Integrity** - Resolved false coverage reports by refactoring `spatial` tests to target actual modular files (`tools/spatial/index.ts`) instead of legacy code.
839
- - **Server Testing** - Added missing test coverage for `McpServer` HTTP/SSE transport startup, OAuth configuration, and error handling.
840
- - **Legacy Cleanup** - Removed unused legacy `spatial.ts` file.
841
- - **Shell Tools Security** - Fixed an injection vulnerability in `mysqlsh_import_table` where `linesTerminatedBy` and `fieldsTerminatedBy` were not properly escaped.
842
- - **Test Improvements**
843
- - Improved test coverage and modularity
844
- - Removed redundant monolithic tool files (`performance.ts`, `text.ts`)
845
- - Enhanced `cli.ts` tests for argument parsing and pool configuration
846
- - Improved `MySQLAdapter` transaction error handling tests
847
- - Added resilience tests for `innodb` resource
848
- - Refactored `ToolFilter` into `ToolConstants`
849
- - Refactored `shell.test.ts` into 5 modular files and improved coverage for shell, spatial, and sysschema tools with meaningful assertions.
850
- - **Resource Test Refactoring** - Split monolithic `handlers.test.ts` and `diagnostics.test.ts` into 10 modular test files (`spatial`, `status`, `sysschema`, `pool`, `processlist`, `capabilities`, `tables`, `innodb`, `performance`, `schema`) to improve maintainability.
851
- - **Coverage Boost** - Achieved >80% branch coverage by adding meaningful edge-case tests for resources (handling null results, empty sets) and tool filters.
852
- - **CLI & Tool Coverage** - Added comprehensive tests for:
853
- - CLI argument parsing (`args.test.ts`)
854
- - Document Store validation (`docstore.test.ts`)
855
- - Performance resource error handling (`performance.test.ts`)
856
- - Schema management tools (`management.test.ts`)
796
+ - Updated `MetaGroup` type in `types/index.ts` to include `ai`
797
+ - Added detailed tool count comments in `ToolFilter.ts`
857
798
 
858
799
  ### Added
859
800
 
801
+ - **Performance Test Suite** - Added `src/__tests__/perf.test.ts` with 11 timing-based tests for regression protection:
802
+ - Tool definition caching validation for `MySQLAdapter.getToolDefinitions()`
803
+ - O(1) lookup verification for `getToolGroup()` (Map vs linear search)
804
+ - Caching validation for `getAllToolNames()` and `parseToolFilter()`
805
+ - Filter performance tests for complex filter chains (-base,-ecosystem,+starter)
806
+
860
807
  - **85 New Tools** for comprehensive MySQL 8.0 coverage (106 → 191 tools total):
861
808
 
862
809
  **Schema Management (10 tools)** - `schema` group:
@@ -908,34 +855,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
908
855
  - `dba` (~70 tools) - DBA tasks (admin, monitoring, security, sysschema, roles)
909
856
  - `ai` (~85 tools) - AI/ML features (docstore, spatial, JSON, stats)
910
857
 
911
- ### Changed
912
-
913
- - Tool groups increased from 15 to 24 (9 new groups)
914
- - JSON tools increased from 12 to 17
915
- - Updated meta-groups: `starter` (~45), `dev` (~65), `base` (~160)
916
- - README updated with new tool groups and meta-groups
917
-
918
- ### Fixed
919
-
920
- - **`ai` meta-group now implemented** - Previously documented in v1.1.0 changelog but missing from code. Now fully functional with 77 tools for AI/ML workloads (JSON, Document Store, spatial, statistics)
921
- - **Tool count accuracy** - Corrected all tool counts in README:
922
- - `starter`: 38 tools (was ~33)
923
- - `dev`: 67 tools (was ~65)
924
- - `ai`: 77 tools (was ~85)
925
- - `dba`: 103 tools (was ~70)
926
- - **README improvements** - Rewrote Tool Filtering section with beginner-friendly explanations, step-by-step filter examples, and syntax reference table
927
-
928
- ### Changed
929
-
930
- - Updated `MetaGroup` type in `types/index.ts` to include `ai`
931
- - Added detailed tool count comments in `ToolFilter.ts`
932
-
933
- ### Added - Documentation
934
-
935
858
  - **MCP Inspector Usage Guide** - Added documentation in README and Wiki for using MCP Inspector to visually test and debug mysql-mcp servers ([Wiki](https://github.com/neverinfamous/mysql-mcp/wiki/MCP-Inspector))
936
859
 
937
- ### Added - Testing
938
-
939
860
  - **Comprehensive Test Suite** - 1168 tests across 54 test files (>95% global statement coverage)
940
861
  - [x] Fix remaining test failures
941
862
  - [x] Achieve 90% test coverage with meaningful tests
@@ -1006,6 +927,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1006
927
  - `performance` tools (coverage for analysis and optimization)
1007
928
  - Resources: `docstore`, `events`, `status`, `variables`, `indexes`, `locks` (now comprehensively tested)
1008
929
 
930
+ ### Fixed
931
+
932
+ - **Test Integrity** - Resolved false coverage reports by refactoring `spatial` tests to target actual modular files (`tools/spatial/index.ts`) instead of legacy code.
933
+ - **Server Testing** - Added missing test coverage for `McpServer` HTTP/SSE transport startup, OAuth configuration, and error handling.
934
+ - **Legacy Cleanup** - Removed unused legacy `spatial.ts` file.
935
+ - **Shell Tools Security** - Fixed an injection vulnerability in `mysqlsh_import_table` where `linesTerminatedBy` and `fieldsTerminatedBy` were not properly escaped.
936
+ - **Test Improvements**
937
+ - Improved test coverage and modularity
938
+ - Removed redundant monolithic tool files (`performance.ts`, `text.ts`)
939
+ - Enhanced `cli.ts` tests for argument parsing and pool configuration
940
+ - Improved `MySQLAdapter` transaction error handling tests
941
+ - Added resilience tests for `innodb` resource
942
+ - Refactored `ToolFilter` into `ToolConstants`
943
+ - Refactored `shell.test.ts` into 5 modular files and improved coverage for shell, spatial, and sysschema tools with meaningful assertions.
944
+ - **Resource Test Refactoring** - Split monolithic `handlers.test.ts` and `diagnostics.test.ts` into 10 modular test files (`spatial`, `status`, `sysschema`, `pool`, `processlist`, `capabilities`, `tables`, `innodb`, `performance`, `schema`) to improve maintainability.
945
+ - **Coverage Boost** - Achieved >80% branch coverage by adding meaningful edge-case tests for resources (handling null results, empty sets) and tool filters.
946
+ - **CLI & Tool Coverage** - Added comprehensive tests for:
947
+ - CLI argument parsing (`args.test.ts`)
948
+ - Document Store validation (`docstore.test.ts`)
949
+ - Performance resource error handling (`performance.test.ts`)
950
+ - Schema management tools (`management.test.ts`)
951
+
952
+ - **`ai` meta-group now implemented** - Previously documented in v1.1.0 changelog but missing from code. Now fully functional with 77 tools for AI/ML workloads (JSON, Document Store, spatial, statistics)
953
+ - **Tool count accuracy** - Corrected all tool counts in README:
954
+ - `starter`: 38 tools (was ~33)
955
+ - `dev`: 67 tools (was ~65)
956
+ - `ai`: 77 tools (was ~85)
957
+ - `dba`: 103 tools (was ~70)
958
+ - **README improvements** - Rewrote Tool Filtering section with beginner-friendly explanations, step-by-step filter examples, and syntax reference table
959
+
1009
960
  ## [1.0.0] - 2025-12-13
1010
961
 
1011
962
  ### Added
package/VERSION CHANGED
@@ -1 +1 @@
1
- 3.0.0
1
+ 3.0.1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neverinfamous/mysql-mcp",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "Enterprise-grade MySQL MCP Server with OAuth 2.0 authentication, connection pooling & tool filtering",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -0,0 +1,20 @@
1
+ # mysql-mcp v3.0.1 Release Notes
2
+
3
+ **Patch release** resolving CodeQL code scanning alerts.
4
+
5
+ ## Fixed
6
+
7
+ - **CodeQL Alert #23** — Removed unused `ValidationError` import in `security_integration.test.ts`
8
+ - **CodeQL Alert #24** — Removed unused `beforeEach` import in `sandbox-factory.test.ts`
9
+
10
+ ## Install
11
+
12
+ ```bash
13
+ npm install -g @neverinfamous/mysql-mcp@3.0.1
14
+ ```
15
+
16
+ ```bash
17
+ docker pull writenotenow/mysql-mcp:v3.0.1
18
+ ```
19
+
20
+ **Full Changelog:** [v3.0.0...v3.0.1](https://github.com/neverinfamous/mysql-mcp/compare/v3.0.0...v3.0.1)
@@ -12,7 +12,6 @@ import {
12
12
  import { getBackupTools } from "../admin/index.js";
13
13
  import { getJsonTools } from "../json/index.js";
14
14
  import type { MySQLAdapter } from "../../MySQLAdapter.js";
15
- import { ValidationError } from "../../../../utils/validators.js";
16
15
 
17
16
  describe("Security: Validation Flow Integration", () => {
18
17
  let mockAdapter: ReturnType<typeof createMockMySQLAdapter>;
@@ -5,7 +5,7 @@
5
5
  * sandbox/pool creation, and mode info retrieval.
6
6
  */
7
7
 
8
- import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
8
+ import { describe, it, expect, vi, afterEach } from "vitest";
9
9
  import {
10
10
  setDefaultSandboxMode,
11
11
  getDefaultSandboxMode,