@berthojoris/mcp-mysql-server 1.40.5 → 1.40.7

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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,29 @@ All notable changes to the MySQL MCP Server will be documented in this file.
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
+ ## [1.40.7] - 2026-05-06
9
+
10
+ ### Added
11
+ - Implemented `export_query_to_csv` end-to-end for SELECT query CSV exports.
12
+ - Enhanced `list_all_tools` with a live runtime tool catalog, enabled/disabled status, access profile, and AI-agent workflow guidance.
13
+
14
+ ### Fixed
15
+ - Fixed `export_query_to_csv` being advertised but failing with `Unknown tool`.
16
+ - Fixed `list_all_tools` returning stale manifest data instead of the active MCP tool catalog.
17
+ - Fixed `execute_in_transaction` permission checks to match its advertised transaction permission.
18
+ - Hardened DDL tools by validating raw DDL statements and checking structured table, column, and index inputs before building SQL.
19
+ - Added argument validation for Cursor bridge dispatches.
20
+
21
+ ## [1.40.6] - 2026-05-04
22
+
23
+ ### Added
24
+ - Added `cursor_execute_request`, a no-argument compatibility bridge for Cursor MCP wrappers that cannot send tool `arguments`.
25
+ - The bridge reads `.cursor/mysql-mcp-request.json` or `MYSQL_MCP_CURSOR_REQUEST_FILE` and dispatches to existing MCP tools or auto-routes SQL to SELECT, write, or DDL execution.
26
+
27
+ ### Changed
28
+ - Updated tool totals in documentation to include the Cursor bridge.
29
+ - Synchronized version metadata to `1.40.6`.
30
+
8
31
  ## [1.40.5] - 2026-04-08
9
32
 
10
33
  ### Fixed
package/DOCUMENTATIONS.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # MySQL MCP Server - Documentation
2
2
 
3
- **Last Updated:** 2026-04-08 14:30:00
4
- **Version:** 1.40.5
5
- **Total Tools:** 62
3
+ **Last Updated:** 2026-05-06 22:38:42
4
+ **Version:** 1.40.7
5
+ **Total Tools:** 79
6
6
 
7
7
  Comprehensive documentation for the MySQL MCP Server. For quick start, see [README.md](README.md).
8
8
 
@@ -65,6 +65,42 @@ Configure MySQL MCP with two access-control layers:
65
65
 
66
66
  ---
67
67
 
68
+ ### Cursor Compatibility Bridge
69
+
70
+ Some Cursor MCP wrappers can call a tool by name but cannot pass `arguments`. For that flow, write a request file at `.cursor/mysql-mcp-request.json` and call the no-argument `cursor_execute_request` tool.
71
+
72
+ Execute any existing MCP tool:
73
+
74
+ ```json
75
+ {
76
+ "tool": "execute_ddl",
77
+ "arguments": {
78
+ "query": "DROP TABLE IF EXISTS spark_processes;"
79
+ }
80
+ }
81
+ ```
82
+
83
+ Or execute SQL directly with automatic routing:
84
+
85
+ ```json
86
+ {
87
+ "query": "DROP TABLE IF EXISTS spark_processes;",
88
+ "mode": "auto"
89
+ }
90
+ ```
91
+
92
+ Supported `mode` values are `auto`, `select`, `write`, and `ddl`. Set `MYSQL_MCP_CURSOR_REQUEST_FILE` to override the request file path.
93
+
94
+ ---
95
+
96
+ ### AI Agent Tool Discovery
97
+
98
+ Use `list_all_tools` first when connecting from Codex, Claude Code CLI, Cursor, Droid CLI, or other MCP agents. It returns the live runtime catalog from the server, enabled/disabled status for each tool, the active permission/category profile, and recommended workflows for common agent tasks.
99
+
100
+ For CSV exports, use `export_table_to_csv` for table-based exports and `export_query_to_csv` for SELECT query exports.
101
+
102
+ ---
103
+
68
104
  ## Permission System
69
105
 
70
106
  ### Available Permissions
@@ -92,12 +128,11 @@ Tool enabled = (Has Permission) AND (Has Category OR No categories specified)
92
128
 
93
129
  ## Tool Categories
94
130
 
95
- ### 1. Database Discovery (5 tools)
131
+ ### 1. Database Discovery (4 tools)
96
132
  - `list_databases` - List all databases
97
133
  - `list_tables` - List tables in database
98
134
  - `read_table_schema` - Get table structure
99
135
  - `get_all_tables_relationships` - Get all FK relationships
100
- - `list_all_tools` - List available MCP tools
101
136
 
102
137
  ### 2. Analysis (4 tools)
103
138
  - `get_database_summary` - Database overview with statistics
@@ -125,7 +160,11 @@ Tool enabled = (Has Permission) AND (Has Category OR No categories specified)
125
160
  - `drop_table` - Delete tables
126
161
  - `execute_ddl` - Execute raw DDL
127
162
 
128
- ### 6. Index Management (10 tools)
163
+ ### 6. Data Export (2 tools)
164
+ - `export_table_to_csv` - Export table data to CSV
165
+ - `export_query_to_csv` - Export SELECT query results to CSV
166
+
167
+ ### 7. Index Management (10 tools)
129
168
  - `list_indexes` - List table indexes
130
169
  - `get_index_info` - Get index details
131
170
  - `create_index` - Create indexes
@@ -137,7 +176,7 @@ Tool enabled = (Has Permission) AND (Has Category OR No categories specified)
137
176
  - `get_fulltext_stats` - Get FULLTEXT index statistics
138
177
  - `optimize_fulltext` - Optimize FULLTEXT indexes
139
178
 
140
- ### 7. Constraint Management (7 tools)
179
+ ### 8. Constraint Management (7 tools)
141
180
  - `list_foreign_keys` - List foreign keys
142
181
  - `list_constraints` - List all constraints
143
182
  - `add_foreign_key` - Add foreign key
@@ -146,7 +185,7 @@ Tool enabled = (Has Permission) AND (Has Category OR No categories specified)
146
185
  - `drop_constraint` - Remove constraint
147
186
  - `add_check_constraint` - Add check constraint
148
187
 
149
- ### 8. Stored Procedures (6 tools)
188
+ ### 9. Stored Procedures (6 tools)
150
189
  - `list_stored_procedures` - List procedures
151
190
  - `get_stored_procedure_info` - Get procedure details
152
191
  - `execute_stored_procedure` - Execute procedures
@@ -154,7 +193,7 @@ Tool enabled = (Has Permission) AND (Has Category OR No categories specified)
154
193
  - `drop_stored_procedure` - Remove procedures
155
194
  - `show_create_procedure` - Show CREATE statement
156
195
 
157
- ### 9. Views Management (6 tools)
196
+ ### 10. Views Management (6 tools)
158
197
  - `list_views` - List views
159
198
  - `get_view_info` - Get view details
160
199
  - `create_view` - Create views
@@ -162,14 +201,14 @@ Tool enabled = (Has Permission) AND (Has Category OR No categories specified)
162
201
  - `drop_view` - Remove views
163
202
  - `show_create_view` - Show CREATE statement
164
203
 
165
- ### 10. Triggers Management (5 tools)
204
+ ### 11. Triggers Management (5 tools)
166
205
  - `list_triggers` - List triggers
167
206
  - `get_trigger_info` - Get trigger details
168
207
  - `create_trigger` - Create triggers
169
208
  - `drop_trigger` - Remove triggers
170
209
  - `show_create_trigger` - Show CREATE statement
171
210
 
172
- ### 11. Table Maintenance (8 tools)
211
+ ### 12. Table Maintenance (8 tools)
173
212
  - `analyze_table` - Update statistics
174
213
  - `optimize_table` - Reclaim space
175
214
  - `check_table` - Check for errors
@@ -179,23 +218,24 @@ Tool enabled = (Has Permission) AND (Has Category OR No categories specified)
179
218
  - `flush_table` - Close/reopen table
180
219
  - `get_table_size` - Get size information
181
220
 
182
- ### 12. Transaction Management (5 tools)
221
+ ### 13. Transaction Management (5 tools)
183
222
  - `begin_transaction` - Start transaction
184
223
  - `commit_transaction` - Commit transaction
185
224
  - `rollback_transaction` - Rollback transaction
186
225
  - `get_transaction_status` - Check transaction state
187
226
  - `execute_in_transaction` - Execute within transaction
188
227
 
189
- ### 13. Query Optimization (3 tools)
228
+ ### 14. Query Optimization (3 tools)
190
229
  - `analyze_query` - Analyze query performance
191
230
  - `get_optimization_hints` - Get optimizer hints
192
231
  - `repair_query` - Repair broken SQL queries
193
232
 
194
- ### 14. Utilities (4 tools)
233
+ ### 15. Utilities (5 tools)
195
234
  - `test_connection` - Test connectivity
196
235
  - `describe_connection` - Connection info
197
236
  - `read_changelog` - Read changelog
198
- - `invalidate_table_cache` - Clear table cache
237
+ - `cursor_execute_request` - Execute a file-backed request for clients that cannot send MCP arguments
238
+ - `list_all_tools` - Runtime tool catalog with agent guidance
199
239
 
200
240
  ---
201
241
 
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  **A production-ready Model Context Protocol (MCP) server for MySQL database integration with AI agents**
6
6
 
7
- **Last Updated:** 2026-04-08 14:30:00
7
+ **Last Updated:** 2026-05-06 22:38:42
8
8
 
9
9
  [![npm version](https://img.shields.io/npm/v/@berthojoris/mcp-mysql-server)](https://www.npmjs.com/package/@berthojoris/mcp-mysql-server)
10
10
  [![npm downloads](https://img.shields.io/npm/dm/@berthojoris/mcp-mysql-server)](https://www.npmjs.com/package/@berthojoris/mcp-mysql-server)
@@ -211,6 +211,40 @@ For more client-specific config snippets, see **[DOCUMENTATIONS.md → Setup & C
211
211
 
212
212
  ---
213
213
 
214
+ ### Cursor Compatibility Bridge
215
+
216
+ If a Cursor MCP wrapper can call tools but cannot send `arguments`, use the no-argument `cursor_execute_request` bridge. Create `.cursor/mysql-mcp-request.json` in the workspace, then call `cursor_execute_request`:
217
+
218
+ ```json
219
+ {
220
+ "tool": "execute_ddl",
221
+ "arguments": {
222
+ "query": "DROP TABLE IF EXISTS spark_processes;"
223
+ }
224
+ }
225
+ ```
226
+
227
+ For direct SQL, the bridge can infer the right SQL tool:
228
+
229
+ ```json
230
+ {
231
+ "query": "DROP TABLE IF EXISTS spark_processes;",
232
+ "mode": "auto"
233
+ }
234
+ ```
235
+
236
+ Set `MYSQL_MCP_CURSOR_REQUEST_FILE` to override the request file path.
237
+
238
+ ---
239
+
240
+ ### AI Agent Tool Discovery
241
+
242
+ For Codex, Claude Code CLI, Cursor, Droid CLI, and other MCP agents, call `list_all_tools` first. It returns the live runtime catalog, enabled/disabled status, active permission/category profile, and recommended workflows for schema exploration, safe SELECT queries, CSV exports, transactions, and data changes.
243
+
244
+ Use `export_table_to_csv` for table-based exports and `export_query_to_csv` for SELECT query exports.
245
+
246
+ ---
247
+
214
248
  ## Permission System
215
249
 
216
250
  Control database access with a **dual-layer filtering system** that provides both broad and fine-grained control:
@@ -250,7 +284,7 @@ Use documentation categories to fine-tune which tools are exposed (Layer 2):
250
284
  | `bulk_operations` | High-performance batch processing operations | `bulk_delete, bulk_insert, bulk_update` |
251
285
  | `custom_queries` | Execute custom SQL queries and advanced operations | `execute_write_query, run_select_query` |
252
286
  | `schema_management` | Manage database schema, tables, and structure | `alter_table, create_table, drop_table, execute_ddl` |
253
- | `utilities` | Database utilities, diagnostics, and helper functions | `describe_connection, export_query_to_csv, export_table_to_csv, list_all_tools, read_changelog, test_connection` |
287
+ | `utilities` | Database utilities, diagnostics, and helper functions | `cursor_execute_request, describe_connection, export_query_to_csv, export_table_to_csv, list_all_tools, read_changelog, test_connection` |
254
288
  | `transaction_management` | Handle ACID transactions and rollback operations | `begin_transaction, commit_transaction, execute_in_transaction, get_transaction_status, rollback_transaction` |
255
289
  | `stored_procedures` | Create, execute, and manage stored procedures | `create_stored_procedure, drop_stored_procedure, execute_stored_procedure, get_stored_procedure_info, list_stored_procedures, show_create_procedure` |
256
290
  | `views_management` | Create and manage database views | `alter_view, create_view, drop_view, get_view_info, list_views, show_create_view` |
@@ -276,7 +310,7 @@ Full category → tool mapping (and examples) lives in **[DOCUMENTATIONS.md →
276
310
 
277
311
  ## Available Tools
278
312
 
279
- The server exposes **62 tools** organized into categories (CRUD, schema, and utilities).
313
+ The server exposes **79 tools** organized into categories (CRUD, schema, and utilities).
280
314
 
281
315
  - Complete list of tools: **[DOCUMENTATIONS.md → Complete Tools Reference](DOCUMENTATIONS.md#🔧-complete-tools-reference)**
282
316
 
@@ -53,7 +53,8 @@ exports.toolCategoryMap = {
53
53
  listDatabases: ToolCategory.LIST,
54
54
  listTables: ToolCategory.LIST,
55
55
  readTableSchema: ToolCategory.LIST,
56
- list_all_tools: ToolCategory.LIST,
56
+ listAllTools: ToolCategory.UTILITY,
57
+ list_all_tools: ToolCategory.UTILITY,
57
58
  // Analysis tools (added here to group with database tools)
58
59
  getDatabaseSummary: ToolCategory.LIST,
59
60
  getSchemaERD: ToolCategory.LIST,
@@ -81,6 +82,8 @@ exports.toolCategoryMap = {
81
82
  executeDdl: ToolCategory.DDL,
82
83
  // Utility tools
83
84
  describeConnection: ToolCategory.UTILITY,
85
+ cursorExecuteRequest: ToolCategory.UTILITY,
86
+ cursor_execute_request: ToolCategory.UTILITY,
84
87
  testConnection: ToolCategory.UTILITY,
85
88
  getAllTablesRelationships: ToolCategory.UTILITY,
86
89
  exportTableToCSV: ToolCategory.UTILITY,
@@ -183,6 +186,8 @@ exports.toolDocCategoryMap = {
183
186
  // Utilities
184
187
  testConnection: DocCategory.UTILITIES,
185
188
  describeConnection: DocCategory.UTILITIES,
189
+ cursorExecuteRequest: DocCategory.UTILITIES,
190
+ cursor_execute_request: DocCategory.UTILITIES,
186
191
  exportTableToCSV: DocCategory.UTILITIES,
187
192
  exportTableToCsv: DocCategory.UTILITIES,
188
193
  export_table_to_csv: DocCategory.UTILITIES,
@@ -190,6 +195,7 @@ exports.toolDocCategoryMap = {
190
195
  exportQueryToCsv: DocCategory.UTILITIES,
191
196
  export_query_to_csv: DocCategory.UTILITIES,
192
197
  read_changelog: DocCategory.UTILITIES,
198
+ listAllTools: DocCategory.UTILITIES,
193
199
  list_all_tools: DocCategory.UTILITIES,
194
200
  // Transaction Management
195
201
  beginTransaction: DocCategory.TRANSACTION_MANAGEMENT,
package/dist/index.d.ts CHANGED
@@ -203,7 +203,19 @@ export declare class MySQLMCP {
203
203
  data?: any;
204
204
  error?: string;
205
205
  }>;
206
- listAllTools(): Promise<{
206
+ listAllTools(params?: {
207
+ tools?: Array<{
208
+ name: string;
209
+ description?: string;
210
+ inputSchema?: any;
211
+ input_schema?: any;
212
+ output_schema?: any;
213
+ }>;
214
+ enabledToolNames?: string[];
215
+ accessProfile?: any;
216
+ serverName?: string;
217
+ serverVersion?: string;
218
+ }): Promise<{
207
219
  status: string;
208
220
  data?: any;
209
221
  error?: string;
@@ -315,6 +327,15 @@ export declare class MySQLMCP {
315
327
  data?: any;
316
328
  error?: string;
317
329
  }>;
330
+ exportQueryToCSV(params: {
331
+ query: string;
332
+ params?: any[];
333
+ include_headers?: boolean;
334
+ }): Promise<{
335
+ status: string;
336
+ data?: any;
337
+ error?: string;
338
+ }>;
318
339
  repairQuery(params: {
319
340
  query: string;
320
341
  error_message?: string;
package/dist/index.js CHANGED
@@ -134,7 +134,7 @@ class MySQLMCP {
134
134
  return { status: "error", error: check.error };
135
135
  }
136
136
  // Additional security check
137
- if (!this.security.isReadOnlyQuery(params.query)) {
137
+ if (!this.security.isReadOnlyQuery(params.query, this.security.hasExecutePermission())) {
138
138
  return {
139
139
  status: "error",
140
140
  error: "Only SELECT queries are allowed with run_select_query. Use execute_write_query for other operations.",
@@ -239,12 +239,12 @@ class MySQLMCP {
239
239
  }
240
240
  return await this.utilityTools.readChangelog(params);
241
241
  }
242
- async listAllTools() {
242
+ async listAllTools(params) {
243
243
  const check = this.checkToolEnabled("list_all_tools");
244
244
  if (!check.enabled) {
245
245
  return { status: "error", error: check.error };
246
246
  }
247
- return await this.utilityTools.listAllTools();
247
+ return await this.utilityTools.listAllTools(params);
248
248
  }
249
249
  // Transaction Tools
250
250
  async beginTransaction(params) {
@@ -276,7 +276,7 @@ class MySQLMCP {
276
276
  return await this.transactionTools.getTransactionStatus();
277
277
  }
278
278
  async executeInTransaction(params) {
279
- const check = this.checkToolEnabled("executeWriteQuery"); // Use executeWriteQuery permission for transaction queries
279
+ const check = this.checkToolEnabled("executeInTransaction");
280
280
  if (!check.enabled) {
281
281
  return { status: "error", error: check.error };
282
282
  }
@@ -333,6 +333,13 @@ class MySQLMCP {
333
333
  }
334
334
  return await this.dataExportTools.exportTableToCSV(params);
335
335
  }
336
+ async exportQueryToCSV(params) {
337
+ const check = this.checkToolEnabled("exportQueryToCSV");
338
+ if (!check.enabled) {
339
+ return { status: "error", error: check.error };
340
+ }
341
+ return await this.dataExportTools.exportQueryToCSV(params);
342
+ }
336
343
  // AI Productivity Tools
337
344
  async repairQuery(params) {
338
345
  const check = this.checkToolEnabled("repairQuery");
@@ -1,6 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
3
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
4
9
  const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
5
10
  const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
6
11
  const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
@@ -12,6 +17,8 @@ const toolArgumentValidation_js_1 = require("./tools/toolArgumentValidation.js")
12
17
  // Layer 2 (Categories): MCP_CATEGORIES (optional, for fine-grained control)
13
18
  const permissions = process.env.MCP_PERMISSIONS || process.env.MCP_CONFIG || "";
14
19
  const categories = process.env.MCP_CATEGORIES || "";
20
+ const SERVER_NAME = "mysql-mcp-server";
21
+ const SERVER_VERSION = "1.40.7";
15
22
  // Declare the MySQL MCP instance (will be initialized in main())
16
23
  let mysqlMCP;
17
24
  // Define all available tools with their schemas
@@ -641,6 +648,14 @@ const TOOLS = [
641
648
  properties: {},
642
649
  },
643
650
  },
651
+ {
652
+ name: "cursor_execute_request",
653
+ description: "Cursor compatibility bridge for clients that can call MCP tools but cannot send arguments. Reads .cursor/mysql-mcp-request.json (or MYSQL_MCP_CURSOR_REQUEST_FILE) and dispatches to the requested MySQL MCP tool. The request file supports {\"tool\":\"execute_ddl\",\"arguments\":{\"query\":\"DROP TABLE IF EXISTS t;\"}} or direct SQL with {\"query\":\"...\",\"mode\":\"auto\"}.",
654
+ inputSchema: {
655
+ type: "object",
656
+ properties: {},
657
+ },
658
+ },
644
659
  {
645
660
  name: "read_changelog",
646
661
  description: "Reads the MySQL MCP Server changelog to see version history, new features, bug fixes, and breaking changes. Useful for understanding tool capabilities and recent updates.",
@@ -1849,8 +1864,8 @@ const TOOLS = [
1849
1864
  ];
1850
1865
  // Create the MCP server
1851
1866
  const server = new index_js_1.Server({
1852
- name: "mysql-mcp-server",
1853
- version: "1.40.5",
1867
+ name: SERVER_NAME,
1868
+ version: SERVER_VERSION,
1854
1869
  }, {
1855
1870
  capabilities: {
1856
1871
  tools: {},
@@ -1865,6 +1880,111 @@ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
1865
1880
  tools: enabledTools,
1866
1881
  };
1867
1882
  });
1883
+ const TOOL_METHOD_OVERRIDES = {
1884
+ get_schema_erd: "getSchemaERD",
1885
+ export_table_to_csv: "exportTableToCSV",
1886
+ export_query_to_csv: "exportQueryToCSV",
1887
+ };
1888
+ const toCamelCase = (value) => value.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
1889
+ const getRuntimeToolCatalog = () => {
1890
+ const enabledTools = (0, toolRegistry_js_1.getEnabledTools)(mysqlMCP, TOOLS);
1891
+ return {
1892
+ tools: TOOLS.map((tool) => ({
1893
+ name: tool.name,
1894
+ description: tool.description,
1895
+ inputSchema: tool.inputSchema,
1896
+ })),
1897
+ enabledToolNames: enabledTools.map((tool) => tool.name),
1898
+ accessProfile: mysqlMCP.getAccessProfile(),
1899
+ serverName: SERVER_NAME,
1900
+ serverVersion: SERVER_VERSION,
1901
+ };
1902
+ };
1903
+ const getCursorRequestFilePath = () => {
1904
+ const configuredPath = process.env.MYSQL_MCP_CURSOR_REQUEST_FILE ||
1905
+ process.env.MCP_MYSQL_REQUEST_FILE ||
1906
+ ".cursor/mysql-mcp-request.json";
1907
+ return path_1.default.isAbsolute(configuredPath)
1908
+ ? configuredPath
1909
+ : path_1.default.resolve(process.cwd(), configuredPath);
1910
+ };
1911
+ const inferSqlToolName = (query, mode = "auto") => {
1912
+ const upperQuery = query.trim().toUpperCase();
1913
+ if (mode === "select")
1914
+ return "run_select_query";
1915
+ if (mode === "write")
1916
+ return "execute_write_query";
1917
+ if (mode === "ddl")
1918
+ return "execute_ddl";
1919
+ if (/^(CREATE|ALTER|DROP|TRUNCATE|RENAME)\b/.test(upperQuery)) {
1920
+ return "execute_ddl";
1921
+ }
1922
+ if (/^(INSERT|UPDATE|DELETE|REPLACE)\b/.test(upperQuery)) {
1923
+ return "execute_write_query";
1924
+ }
1925
+ if (/^(SELECT|WITH)\b/.test(upperQuery)) {
1926
+ return "run_select_query";
1927
+ }
1928
+ throw new Error("Unable to infer SQL tool. Set mode to one of: select, write, ddl.");
1929
+ };
1930
+ const executeToolByName = async (toolName, args = {}) => {
1931
+ const knownToolNames = new Set(TOOLS.map((tool) => tool.name));
1932
+ if (!knownToolNames.has(toolName)) {
1933
+ throw new Error(`Unknown tool for Cursor bridge: ${toolName}`);
1934
+ }
1935
+ if (toolName === "cursor_execute_request") {
1936
+ throw new Error("cursor_execute_request cannot dispatch to itself");
1937
+ }
1938
+ const validation = (0, toolArgumentValidation_js_1.validateToolArguments)(toolName, args);
1939
+ if (!validation.valid) {
1940
+ throw new Error(`Validation Error: ${validation.errors?.join(", ") || "Invalid arguments"}`);
1941
+ }
1942
+ if (toolName === "list_all_tools") {
1943
+ return await mysqlMCP.listAllTools(getRuntimeToolCatalog());
1944
+ }
1945
+ const methodName = TOOL_METHOD_OVERRIDES[toolName] || toCamelCase(toolName);
1946
+ const method = mysqlMCP[methodName];
1947
+ if (typeof method !== "function") {
1948
+ throw new Error(`No handler method found for Cursor bridge tool: ${toolName}`);
1949
+ }
1950
+ return await method.call(mysqlMCP, args);
1951
+ };
1952
+ const executeCursorRequest = async () => {
1953
+ const requestFilePath = getCursorRequestFilePath();
1954
+ if (!fs_1.default.existsSync(requestFilePath)) {
1955
+ return {
1956
+ status: "error",
1957
+ error: `Cursor request file not found: ${requestFilePath}. ` +
1958
+ 'Create it with JSON like {"tool":"execute_ddl","arguments":{"query":"DROP TABLE IF EXISTS spark_processes;"}}',
1959
+ };
1960
+ }
1961
+ let request;
1962
+ try {
1963
+ request = JSON.parse(fs_1.default.readFileSync(requestFilePath, "utf8"));
1964
+ }
1965
+ catch (error) {
1966
+ return {
1967
+ status: "error",
1968
+ error: `Failed to read Cursor request file: ${error.message}`,
1969
+ };
1970
+ }
1971
+ const requestedTool = request.tool || request.toolName || request.name;
1972
+ if (requestedTool) {
1973
+ return await executeToolByName(requestedTool, request.arguments || request.args || {});
1974
+ }
1975
+ if (request.query) {
1976
+ const inferredTool = inferSqlToolName(request.query, request.mode || "auto");
1977
+ return await executeToolByName(inferredTool, {
1978
+ query: request.query,
1979
+ params: request.params,
1980
+ dry_run: request.dry_run,
1981
+ });
1982
+ }
1983
+ return {
1984
+ status: "error",
1985
+ error: "Cursor request must contain either tool/toolName/name with arguments, or query with optional mode.",
1986
+ };
1987
+ };
1868
1988
  // Handle tool call requests
1869
1989
  server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
1870
1990
  const { name, arguments: args } = request.params;
@@ -1951,11 +2071,14 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
1951
2071
  case "describe_connection":
1952
2072
  result = await mysqlMCP.describeConnection();
1953
2073
  break;
2074
+ case "cursor_execute_request":
2075
+ result = await executeCursorRequest();
2076
+ break;
1954
2077
  case "test_connection":
1955
2078
  result = await mysqlMCP.testConnection();
1956
2079
  break;
1957
2080
  case "list_all_tools":
1958
- result = await mysqlMCP.listAllTools();
2081
+ result = await mysqlMCP.listAllTools(getRuntimeToolCatalog());
1959
2082
  break;
1960
2083
  case "read_changelog":
1961
2084
  result = await mysqlMCP.readChangelog((args || {}));
@@ -2002,6 +2125,9 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
2002
2125
  case "export_table_to_csv":
2003
2126
  result = await mysqlMCP.exportTableToCSV((args || {}));
2004
2127
  break;
2128
+ case "export_query_to_csv":
2129
+ result = await mysqlMCP.exportQueryToCSV((args || {}));
2130
+ break;
2005
2131
  // Query Optimization Tools
2006
2132
  case "analyze_query":
2007
2133
  result = mysqlMCP.analyzeQuery((args || {}));
@@ -71,7 +71,7 @@ export declare class SecurityLayer {
71
71
  /**
72
72
  * Check if a query is a read-only SELECT query or information query (SHOW, DESCRIBE, etc.)
73
73
  */
74
- isReadOnlyQuery(query: string): boolean;
74
+ isReadOnlyQuery(query: string, bypassDangerousCheck?: boolean): boolean;
75
75
  /**
76
76
  * Check if a query contains dangerous operations
77
77
  */
@@ -404,13 +404,13 @@ class SecurityLayer {
404
404
  /**
405
405
  * Check if a query is a read-only SELECT query or information query (SHOW, DESCRIBE, etc.)
406
406
  */
407
- isReadOnlyQuery(query) {
407
+ isReadOnlyQuery(query, bypassDangerousCheck = false) {
408
408
  // Check if it's an information query first (SHOW, DESCRIBE, EXPLAIN, etc.)
409
409
  if (this.isInformationQuery(query)) {
410
410
  return true;
411
411
  }
412
412
  // Check if it's a SELECT query
413
- const validation = this.validateQuery(query);
413
+ const validation = this.validateQuery(query, bypassDangerousCheck);
414
414
  return validation.valid && validation.queryType === "SELECT";
415
415
  }
416
416
  /**
@@ -12,6 +12,8 @@ export declare class DataExportTools {
12
12
  * Escape string value for SQL INSERT statements
13
13
  */
14
14
  private escapeValue;
15
+ private escapeCsvValue;
16
+ private rowsToCSV;
15
17
  /**
16
18
  * Export table data to CSV format
17
19
  */
@@ -26,4 +28,13 @@ export declare class DataExportTools {
26
28
  data?: any;
27
29
  error?: string;
28
30
  }>;
31
+ exportQueryToCSV(queryParams: {
32
+ query: string;
33
+ params?: any[];
34
+ include_headers?: boolean;
35
+ }): Promise<{
36
+ status: string;
37
+ data?: any;
38
+ error?: string;
39
+ }>;
29
40
  }