@yanzhang123/readonly-db-mcp 0.7.2 → 0.7.3

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/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2024 Dana K. Williams
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Dana K. Williams
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
package/README.md CHANGED
@@ -1,15 +1,15 @@
1
1
  [![Tests](https://github.com/12zhangyan/mysql_mcp_server/actions/workflows/test.yml/badge.svg)](https://github.com/12zhangyan/mysql_mcp_server/actions)
2
- [![PyPI - Downloads](https://img.shields.io/pypi/dm/mysql-mcp-server)](https://pypi.org/project/mysql-mcp-server/)
3
- [![AgentAudit Safe](https://img.shields.io/badge/AgentAudit-safe-brightgreen)](https://www.agentaudit.dev/packages/mysql-mcp-server)
4
- # MySQL MCP Server
5
- A Model Context Protocol (MCP) implementation that enables secure interaction with MySQL databases. This server component facilitates communication between AI applications (hosts/clients) and MySQL databases, making database exploration and analysis safer and more structured through a controlled interface.
6
-
7
- > **Note**: MySQL MCP Server supports both standard input/output (STDIO) and Streamable HTTP (SSE) transport modes. The SSE mode is recommended for remote/self-hosted deployments.
8
-
9
- ## Deployment options
10
- - **Hosted** — [Fronteir AI](https://fronteir.ai/mcp/designcomputer-mysql-mcp-server) runs the server for you; no local setup required.
11
- - **Local** — [Smithery](https://smithery.ai/server/designcomputer/mysql-mcp-server) installs and runs the server on your own machine.
12
-
2
+ [![PyPI - Downloads](https://img.shields.io/pypi/dm/mysql-mcp-server)](https://pypi.org/project/mysql-mcp-server/)
3
+ [![AgentAudit Safe](https://img.shields.io/badge/AgentAudit-safe-brightgreen)](https://www.agentaudit.dev/packages/mysql-mcp-server)
4
+ # MySQL MCP Server
5
+ A Model Context Protocol (MCP) implementation that enables secure interaction with MySQL databases. This server component facilitates communication between AI applications (hosts/clients) and MySQL databases, making database exploration and analysis safer and more structured through a controlled interface.
6
+
7
+ > **Note**: MySQL MCP Server supports both standard input/output (STDIO) and Streamable HTTP (SSE) transport modes. The SSE mode is recommended for remote/self-hosted deployments.
8
+
9
+ ## Deployment options
10
+ - **Hosted** — [Fronteir AI](https://fronteir.ai/mcp/designcomputer-mysql-mcp-server) runs the server for you; no local setup required.
11
+ - **Local** — [Smithery](https://smithery.ai/server/designcomputer/mysql-mcp-server) installs and runs the server on your own machine.
12
+
13
13
  ## Features
14
14
  - **Named connection profiles** for dev/test/staging/prod and multiple servers
15
15
  - Select a `connection` and `database` independently on every tool call
@@ -20,7 +20,7 @@ A Model Context Protocol (MCP) implementation that enables secure interaction wi
20
20
  - **SSE/HTTP transport support** (`MCP_TRANSPORT=sse`)
21
21
  - Per-profile SSL/TLS and SSH tunneling
22
22
  - Passwords can stay in environment variables instead of the profiles file
23
-
23
+
24
24
  ## Installation
25
25
 
26
26
  ### npm / npx
@@ -43,21 +43,21 @@ For MCP clients, use `npx` as the command and
43
43
  `["-y", "@yanzhang123/readonly-db-mcp"]` as its arguments.
44
44
 
45
45
  ### Manual Installation
46
- ```bash
47
- pip install mysql-mcp-server
48
- ```
49
-
50
- ### Installing via Smithery
51
- To install MySQL MCP Server for Claude Desktop automatically via [Smithery](https://smithery.ai/server/designcomputer/mysql-mcp-server):
52
- ```bash
53
- npx -y @smithery/cli install designcomputer/mysql-mcp-server --client claude
54
- ```
55
-
56
- ### Installing via Claude Code CLI
57
- ```bash
58
- claude mcp add --transport stdio designcomputer-mysql_mcp_server uvx mysql_mcp_server
59
- ```
60
-
46
+ ```bash
47
+ pip install mysql-mcp-server
48
+ ```
49
+
50
+ ### Installing via Smithery
51
+ To install MySQL MCP Server for Claude Desktop automatically via [Smithery](https://smithery.ai/server/designcomputer/mysql-mcp-server):
52
+ ```bash
53
+ npx -y @smithery/cli install designcomputer/mysql-mcp-server --client claude
54
+ ```
55
+
56
+ ### Installing via Claude Code CLI
57
+ ```bash
58
+ claude mcp add --transport stdio designcomputer-mysql_mcp_server uvx mysql_mcp_server
59
+ ```
60
+
61
61
  ## Configuration
62
62
 
63
63
  ### Recommended: named connections
@@ -163,8 +163,8 @@ MYSQL_PORT=3306 # Optional: Database port (defaults to 3306 if not speci
163
163
  MYSQL_USER=readonly_user
164
164
  MYSQL_PASSWORD=your_password
165
165
  MYSQL_DATABASE=your_database # Optional: Omit for multi-database mode
166
-
167
- # Advanced Configuration
166
+
167
+ # Advanced Configuration
168
168
  MYSQL_SSL_MODE=REQUIRED # DISABLED, REQUIRED, VERIFY_CA, VERIFY_IDENTITY
169
169
  MYSQL_SSL_CA= # required for VERIFY_CA / VERIFY_IDENTITY
170
170
  MYSQL_CONNECT_TIMEOUT=10 # Timeout in seconds
@@ -183,18 +183,18 @@ MYSQL_AUDIT_REQUIRED_CONTEXT=actor,purpose,ticket_id
183
183
  MYSQL_AUDIT_FAIL_CLOSED=true
184
184
  MYSQL_AUDIT_FSYNC=true
185
185
  MYSQL_ALLOWED_DATABASES=your_database
186
-
187
- # Connection behaviour (Optional)
188
- MYSQL_SQL_MODE=TRADITIONAL # SQL mode applied to the connection (default: TRADITIONAL)
189
-
190
- # Compatibility (Optional)
191
- MYSQL_CHARSET=utf8mb4
192
- MYSQL_COLLATION=utf8mb4_unicode_ci
193
- MYSQL_AUTH_PLUGIN= # e.g., mysql_native_password for older MySQL versions
194
- MYSQL_USE_PURE=false # Force the pure-Python connector (default: false)
195
- MYSQL_RAISE_ON_WARNINGS=false # Raise on SQL warnings (default: false)
196
-
197
- # SSE Transport (Optional)
186
+
187
+ # Connection behaviour (Optional)
188
+ MYSQL_SQL_MODE=TRADITIONAL # SQL mode applied to the connection (default: TRADITIONAL)
189
+
190
+ # Compatibility (Optional)
191
+ MYSQL_CHARSET=utf8mb4
192
+ MYSQL_COLLATION=utf8mb4_unicode_ci
193
+ MYSQL_AUTH_PLUGIN= # e.g., mysql_native_password for older MySQL versions
194
+ MYSQL_USE_PURE=false # Force the pure-Python connector (default: false)
195
+ MYSQL_RAISE_ON_WARNINGS=false # Raise on SQL warnings (default: false)
196
+
197
+ # SSE Transport (Optional)
198
198
  MCP_TRANSPORT=stdio # stdio or sse
199
199
  MCP_SSE_HOST=127.0.0.1 # Safe default: loopback only
200
200
  PORT=8000 # HTTP port (fallback for MCP_SSE_PORT)
@@ -202,30 +202,30 @@ MCP_SSE_ALLOWED_HOSTS= # Comma-separated allowed Host headers (default: localh
202
202
  MCP_SSE_BEARER_TOKEN= # Optional; at least 32 characters
203
203
  # Set only when an authenticated reverse proxy is the sole network entry point:
204
204
  MCP_SSE_TRUST_PROXY_AUTH=false
205
-
206
- # SSH Tunneling (Optional)
207
- MYSQL_SSH_ENABLE=false # Set to true to enable
208
- MYSQL_SSH_HOST= # SSH jump host
209
- MYSQL_SSH_PORT=22 # SSH port
210
- MYSQL_SSH_USER= # SSH username
211
- MYSQL_SSH_KEY_PATH= # Path to SSH private key
212
- MYSQL_SSH_REMOTE_HOST=localhost # Host from the perspective of the jump host
213
- MYSQL_SSH_REMOTE_PORT=3306
205
+
206
+ # SSH Tunneling (Optional)
207
+ MYSQL_SSH_ENABLE=false # Set to true to enable
208
+ MYSQL_SSH_HOST= # SSH jump host
209
+ MYSQL_SSH_PORT=22 # SSH port
210
+ MYSQL_SSH_USER= # SSH username
211
+ MYSQL_SSH_KEY_PATH= # Path to SSH private key
212
+ MYSQL_SSH_REMOTE_HOST=localhost # Host from the perspective of the jump host
213
+ MYSQL_SSH_REMOTE_PORT=3306
214
214
  MYSQL_LOCAL_PORT=0 # 0 selects a free port; the tunnel is reused
215
215
  ```
216
-
217
- ### `.env` file loading
218
-
219
- On startup the server automatically loads a `.env` file via `python-dotenv`, so for local use you can simply:
220
-
221
- ```bash
222
- cp .env.example .env # then edit with your credentials
223
- ```
224
-
225
- The file is read from the **process working directory** (and parent directories), which works when you run the server yourself from the project folder.
226
-
227
- > ⚠️ **Claude Code / Claude Desktop:** these hosts launch the server from their own working directory, so the project's `.env` will **not** be found and you'll see `Missing required database configuration`. Put your `MYSQL_*` values in the `env` block of the MCP config (shown in the Usage section below) rather than relying on `.env`.
228
-
216
+
217
+ ### `.env` file loading
218
+
219
+ On startup the server automatically loads a `.env` file via `python-dotenv`, so for local use you can simply:
220
+
221
+ ```bash
222
+ cp .env.example .env # then edit with your credentials
223
+ ```
224
+
225
+ The file is read from the **process working directory** (and parent directories), which works when you run the server yourself from the project folder.
226
+
227
+ > ⚠️ **Claude Code / Claude Desktop:** these hosts launch the server from their own working directory, so the project's `.env` will **not** be found and you'll see `Missing required database configuration`. Put your `MYSQL_*` values in the `env` block of the MCP config (shown in the Usage section below) rather than relying on `.env`.
228
+
229
229
  ### Multi-database mode
230
230
 
231
231
  When `MYSQL_DATABASE` is not set, the server operates in multi-database mode:
@@ -275,114 +275,114 @@ Executes exactly one read-only statement.
275
275
  ### `get_schema_info`
276
276
  Provides detailed metadata about database structures.
277
277
  - **Arguments:** `table_name`, `connection`, `database` (all optional)
278
- - **Output:** Column names, types, nullability, default values, and comments.
279
- - **Cross-database:** Pass `database.table` to query a table outside `MYSQL_DATABASE`; bare names use the configured database.
280
- - **Identifier rules:** Names must contain only alphanumeric characters, underscores, and `$` (dots are allowed as a separator between database and table names).
281
-
278
+ - **Output:** Column names, types, nullability, default values, and comments.
279
+ - **Cross-database:** Pass `database.table` to query a table outside `MYSQL_DATABASE`; bare names use the configured database.
280
+ - **Identifier rules:** Names must contain only alphanumeric characters, underscores, and `$` (dots are allowed as a separator between database and table names).
281
+
282
282
  ### `get_table_sample`
283
283
  Fetches a representative sample of data.
284
284
  - **Arguments:** `table_name` (required), `limit` (optional integer, max 100), `offset`, `connection`, `database`, `timeout_ms`, `result_format`
285
- - **Use Case:** Quickly understand data formats and content without fetching large result sets.
286
- - **Cross-database:** Pass `database.table` to sample a table outside `MYSQL_DATABASE`; bare names use the configured database.
287
- - **Identifier rules:** Names must contain only alphanumeric characters, underscores, and `$` (dots are allowed as a separator between database and table names).
288
-
289
- ## Available Prompts
290
-
291
- In addition to tools, the server exposes **MCP prompts** — guided, multi-step workflows that a client can launch on demand. In Claude Code they appear as slash commands (`/mcp__<server>__<prompt>`); in Claude Desktop they appear in the prompts (`+`) menu.
292
-
293
- | Prompt | Arguments | Description |
294
- | --- | --- | --- |
285
+ - **Use Case:** Quickly understand data formats and content without fetching large result sets.
286
+ - **Cross-database:** Pass `database.table` to sample a table outside `MYSQL_DATABASE`; bare names use the configured database.
287
+ - **Identifier rules:** Names must contain only alphanumeric characters, underscores, and `$` (dots are allowed as a separator between database and table names).
288
+
289
+ ## Available Prompts
290
+
291
+ In addition to tools, the server exposes **MCP prompts** — guided, multi-step workflows that a client can launch on demand. In Claude Code they appear as slash commands (`/mcp__<server>__<prompt>`); in Claude Desktop they appear in the prompts (`+`) menu.
292
+
293
+ | Prompt | Arguments | Description |
294
+ | --- | --- | --- |
295
295
  | `explore_database` | `connection`, `database` *(optional)* | Systematically explore the selected database: discover tables, inspect schemas, sample data, and summarize it. |
296
296
  | `analyze_table` | `table_name` *(required)*; `connection`, `database` *(optional)* | Deep-dive into a specific table. Accepts `database.table` notation. |
297
-
298
- **Example (Claude Code):**
299
- ```
300
- /mcp__mysql__explore_database
301
- /mcp__mysql__analyze_table customers
302
- ```
303
-
297
+
298
+ **Example (Claude Code):**
299
+ ```
300
+ /mcp__mysql__explore_database
301
+ /mcp__mysql__analyze_table customers
302
+ ```
303
+
304
304
  Both prompts orchestrate the read-only discovery, schema, and sampling tools.
305
-
306
- ## Usage
307
- ### With Claude Desktop
308
- Add this to your `claude_desktop_config.json`:
309
- ```json
310
- {
311
- "mcpServers": {
312
- "mysql": {
313
- "command": "uv",
314
- "args": [
315
- "--directory",
316
- "path/to/mysql_mcp_server",
317
- "run",
318
- "mysql_mcp_server"
305
+
306
+ ## Usage
307
+ ### With Claude Desktop
308
+ Add this to your `claude_desktop_config.json`:
309
+ ```json
310
+ {
311
+ "mcpServers": {
312
+ "mysql": {
313
+ "command": "uv",
314
+ "args": [
315
+ "--directory",
316
+ "path/to/mysql_mcp_server",
317
+ "run",
318
+ "mysql_mcp_server"
319
319
  ],
320
320
  "env": {
321
321
  "MYSQL_PROFILES_FILE": "C:/absolute/path/mysql-connections.toml",
322
322
  "MYSQL_DEV_PASSWORD": "your_dev_password",
323
323
  "MYSQL_PROD_PASSWORD": "your_prod_password"
324
324
  }
325
- }
326
- }
327
- }
328
- ```
329
-
330
- For more detailed examples and agent-specific guidance, see [MCP_USECASES.md](MCP_USECASES.md).
331
-
332
- ### With Visual Studio Code
333
- Add this to your `mcp.json`:
334
- ```json
335
- {
336
- "mcpServers": {
337
- "mysql": {
338
- "type": "stdio",
339
- "command": "uvx",
340
- "args": [
341
- "--from",
342
- "mysql-mcp-server",
343
- "mysql_mcp_server"
325
+ }
326
+ }
327
+ }
328
+ ```
329
+
330
+ For more detailed examples and agent-specific guidance, see [MCP_USECASES.md](MCP_USECASES.md).
331
+
332
+ ### With Visual Studio Code
333
+ Add this to your `mcp.json`:
334
+ ```json
335
+ {
336
+ "mcpServers": {
337
+ "mysql": {
338
+ "type": "stdio",
339
+ "command": "uvx",
340
+ "args": [
341
+ "--from",
342
+ "mysql-mcp-server",
343
+ "mysql_mcp_server"
344
344
  ],
345
345
  "env": {
346
346
  "MYSQL_PROFILES_FILE": "C:/absolute/path/mysql-connections.toml",
347
347
  "MYSQL_DEV_PASSWORD": "your_dev_password",
348
348
  "MYSQL_PROD_PASSWORD": "your_prod_password"
349
349
  }
350
- }
351
- }
352
- }
353
- ```
354
- Note: Will need to install uv for this to work
355
-
356
- ### Debugging with MCP Inspector
357
- While MySQL MCP Server isn't intended to be run standalone or directly from the command line with Python, you can use the MCP Inspector to debug it.
358
-
359
- The MCP Inspector provides a convenient way to test and debug your MCP implementation:
360
-
361
- ```bash
362
- # Install dependencies
363
- pip install -r requirements.txt
364
- # Use the MCP Inspector for debugging (do not run directly with Python)
365
- ```
366
-
367
- The MySQL MCP Server is designed to be integrated with AI applications like Claude Desktop and should not be run directly as a standalone Python program.
368
-
369
- ## Development
370
- ```bash
371
- # Clone the repository
350
+ }
351
+ }
352
+ }
353
+ ```
354
+ Note: Will need to install uv for this to work
355
+
356
+ ### Debugging with MCP Inspector
357
+ While MySQL MCP Server isn't intended to be run standalone or directly from the command line with Python, you can use the MCP Inspector to debug it.
358
+
359
+ The MCP Inspector provides a convenient way to test and debug your MCP implementation:
360
+
361
+ ```bash
362
+ # Install dependencies
363
+ pip install -r requirements.txt
364
+ # Use the MCP Inspector for debugging (do not run directly with Python)
365
+ ```
366
+
367
+ The MySQL MCP Server is designed to be integrated with AI applications like Claude Desktop and should not be run directly as a standalone Python program.
368
+
369
+ ## Development
370
+ ```bash
371
+ # Clone the repository
372
372
  git clone https://github.com/12zhangyan/mysql_mcp_server.git
373
- cd mysql_mcp_server
374
- # Create virtual environment
375
- python -m venv venv
376
- source venv/bin/activate # or `venv\Scripts\activate` on Windows
377
- # Install development dependencies
378
- pip install -r requirements-dev.txt
379
- # Copy the example config and edit with your credentials
380
- cp .env.example .env
381
- # Edit .env with your MySQL connection details
382
- # Run tests
383
- pytest
384
- ```
385
-
373
+ cd mysql_mcp_server
374
+ # Create virtual environment
375
+ python -m venv venv
376
+ source venv/bin/activate # or `venv\Scripts\activate` on Windows
377
+ # Install development dependencies
378
+ pip install -r requirements-dev.txt
379
+ # Copy the example config and edit with your credentials
380
+ cp .env.example .env
381
+ # Edit .env with your MySQL connection details
382
+ # Run tests
383
+ pytest
384
+ ```
385
+
386
386
  ## Security Considerations
387
387
  - **Read-only SQL gate:** Only result-producing read statements are accepted; write/DDL/transaction/locking constructs are rejected before a connection is opened.
388
388
  - **Database enforcement:** Every exposed query runs with `autocommit=false` in a read-only transaction. Normal completion rolls back; cancellation or truncation closes the socket and forces server-side rollback.
@@ -401,50 +401,50 @@ pytest
401
401
  - **Diagnostic Privacy:** Connection diagnostics expose an account fingerprint and privilege summary, not raw usernames or `SHOW GRANTS`; configuration paths and database-supplied error text are redacted.
402
402
  - **Least Privilege:** A dedicated `SELECT` account is recommended as additional defense, but it is not assumed by the MCP read-only enforcement. `check_connection` warns about broader grants without disabling the profile.
403
403
  - **SSE is loopback-only by default.** Configure `MCP_SSE_BEARER_TOKEN` with at least 32 characters to enable built-in bearer authentication. A non-loopback bind is refused unless bearer authentication is enabled or `MCP_SSE_TRUST_PROXY_AUTH=true` explicitly confirms that an authenticated reverse proxy is the only network entry point. Example with nginx and HTTP Basic Auth:
404
-
405
- ```nginx
406
- location /sse {
407
- auth_basic "MCP";
408
- auth_basic_user_file /etc/nginx/.htpasswd;
409
- proxy_pass http://127.0.0.1:8000;
410
- proxy_set_header Host $host;
411
- proxy_buffering off;
412
- }
413
- location /messages/ {
414
- auth_basic "MCP";
415
- auth_basic_user_file /etc/nginx/.htpasswd;
416
- proxy_pass http://127.0.0.1:8000;
417
- proxy_set_header Host $host;
418
- }
419
- ```
420
-
404
+
405
+ ```nginx
406
+ location /sse {
407
+ auth_basic "MCP";
408
+ auth_basic_user_file /etc/nginx/.htpasswd;
409
+ proxy_pass http://127.0.0.1:8000;
410
+ proxy_set_header Host $host;
411
+ proxy_buffering off;
412
+ }
413
+ location /messages/ {
414
+ auth_basic "MCP";
415
+ auth_basic_user_file /etc/nginx/.htpasswd;
416
+ proxy_pass http://127.0.0.1:8000;
417
+ proxy_set_header Host $host;
418
+ }
419
+ ```
420
+
421
421
  Keep `MCP_SSE_HOST=127.0.0.1` so the proxy is the sole public entry point. If a container requires `0.0.0.0`, set `MCP_SSE_TRUST_PROXY_AUTH=true` only after network policy prevents direct access. Set `MCP_SSE_ALLOWED_HOSTS` to the hostname forwarded by the proxy.
422
422
 
423
423
  See [SECURITY.md](SECURITY.md) and [ENTERPRISE_DEPLOYMENT.md](ENTERPRISE_DEPLOYMENT.md) for deployment and audit guidance.
424
424
  Maintainers should follow [RELEASING.md](RELEASING.md) for synchronized Python/npm version releases.
425
-
426
- ## Security Best Practices
427
- This MCP implementation requires database access to function. For security:
425
+
426
+ ## Security Best Practices
427
+ This MCP implementation requires database access to function. For security:
428
428
  1. **Create a dedicated MySQL user** with `SELECT` only
429
- 2. **Never use root credentials** or administrative accounts
430
- 3. **Restrict database access** to only necessary operations
431
- 4. **Enable logging** for audit purposes
432
- 5. **Regular security reviews** of database access
433
-
429
+ 2. **Never use root credentials** or administrative accounts
430
+ 3. **Restrict database access** to only necessary operations
431
+ 4. **Enable logging** for audit purposes
432
+ 5. **Regular security reviews** of database access
433
+
434
434
  See [MySQL Security Configuration Guide](https://github.com/12zhangyan/mysql_mcp_server/blob/main/SECURITY.md) for detailed instructions on:
435
- - Creating a restricted MySQL user
436
- - Setting appropriate permissions
437
- - Monitoring database access
438
- - Security best practices
439
-
440
- ⚠️ IMPORTANT: Always follow the principle of least privilege when configuring database access.
441
-
442
- ## License
443
- MIT License - see LICENSE file for details.
444
-
445
- ## Contributing
446
- 1. Fork the repository
447
- 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
448
- 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
449
- 4. Push to the branch (`git push origin feature/amazing-feature`)
450
- 5. Open a Pull Request
435
+ - Creating a restricted MySQL user
436
+ - Setting appropriate permissions
437
+ - Monitoring database access
438
+ - Security best practices
439
+
440
+ ⚠️ IMPORTANT: Always follow the principle of least privilege when configuring database access.
441
+
442
+ ## License
443
+ MIT License - see LICENSE file for details.
444
+
445
+ ## Contributing
446
+ 1. Fork the repository
447
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
448
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
449
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
450
+ 5. Open a Pull Request
package/SECURITY.md CHANGED
@@ -1,137 +1,137 @@
1
- ## MySQL Security Configuration
2
-
3
- ### Creating a Restricted MySQL User
4
-
5
- It's crucial to create a dedicated MySQL user with minimal permissions for the MCP server. Never use the root account or a user with full administrative privileges.
6
-
7
- #### 1. Create a new MySQL user
8
-
9
- ```sql
10
- -- Connect as root or administrator
11
- CREATE USER 'mcp_user'@'localhost' IDENTIFIED BY 'your_secure_password';
12
- ```
13
-
14
- #### 2. Grant minimal required permissions
15
-
16
- Basic read-only access (recommended for exploration and analysis):
17
- ```sql
18
- -- Grant SELECT permission only
19
- GRANT SELECT ON your_database.* TO 'mcp_user'@'localhost';
20
- ```
21
-
1
+ ## MySQL Security Configuration
2
+
3
+ ### Creating a Restricted MySQL User
4
+
5
+ It's crucial to create a dedicated MySQL user with minimal permissions for the MCP server. Never use the root account or a user with full administrative privileges.
6
+
7
+ #### 1. Create a new MySQL user
8
+
9
+ ```sql
10
+ -- Connect as root or administrator
11
+ CREATE USER 'mcp_user'@'localhost' IDENTIFIED BY 'your_secure_password';
12
+ ```
13
+
14
+ #### 2. Grant minimal required permissions
15
+
16
+ Basic read-only access (recommended for exploration and analysis):
17
+ ```sql
18
+ -- Grant SELECT permission only
19
+ GRANT SELECT ON your_database.* TO 'mcp_user'@'localhost';
20
+ ```
21
+
22
22
  Do not grant `INSERT`, `UPDATE`, `DELETE`, DDL, routine execution, file, lock, or
23
23
  temporary-table privileges to the MCP account. The server rejects those operations,
24
24
  and MySQL permissions provide the final security boundary.
25
-
26
- #### 3. Apply the permissions
27
- ```sql
28
- FLUSH PRIVILEGES;
29
- ```
30
-
31
- ### Additional Security Measures
32
-
33
- 1. **Network Access**
34
- - Restrict the user to connecting only from localhost if the MCP server runs on the same machine
35
- - If remote access is needed, specify exact IP addresses rather than using wildcards
36
-
37
- 2. **Query Restrictions**
38
- - Consider using VIEWs to further restrict data access
25
+
26
+ #### 3. Apply the permissions
27
+ ```sql
28
+ FLUSH PRIVILEGES;
29
+ ```
30
+
31
+ ### Additional Security Measures
32
+
33
+ 1. **Network Access**
34
+ - Restrict the user to connecting only from localhost if the MCP server runs on the same machine
35
+ - If remote access is needed, specify exact IP addresses rather than using wildcards
36
+
37
+ 2. **Query Restrictions**
38
+ - Consider using VIEWs to further restrict data access
39
39
  - Set an appropriate `max_queries_per_hour` limit:
40
- ```sql
41
- ALTER USER 'mcp_user'@'localhost'
40
+ ```sql
41
+ ALTER USER 'mcp_user'@'localhost'
42
42
  WITH MAX_QUERIES_PER_HOUR 1000;
43
- ```
44
-
45
- 3. **Data Access Control**
46
- - Grant access only to specific tables when possible
47
- - Use column-level permissions for sensitive data:
48
- ```sql
49
- GRANT SELECT (public_column1, public_column2)
50
- ON your_database.sensitive_table TO 'mcp_user'@'localhost';
51
- ```
52
-
53
- 4. **Regular Auditing**
54
- - Enable MySQL audit logging for the MCP user
55
- - Regularly review logs for unusual patterns
56
- - Periodically review and adjust permissions
57
-
58
- ### Environment Configuration
59
-
60
- When setting up the MCP server, use these restricted credentials in your environment:
61
-
62
- ```bash
63
- MYSQL_USER=mcp_user
64
- MYSQL_PASSWORD=your_secure_password
65
- MYSQL_DATABASE=your_database
66
- MYSQL_HOST=localhost
67
- ```
68
-
69
- ### Monitoring Usage
70
-
71
- To monitor the MCP user's database usage:
72
-
73
- ```sql
74
- -- Check current connections
75
- SELECT * FROM information_schema.PROCESSLIST
76
- WHERE user = 'mcp_user';
77
-
78
- -- View user privileges
79
- SHOW GRANTS FOR 'mcp_user'@'localhost';
80
-
81
- -- Check resource limits
82
- SELECT * FROM mysql.user
83
- WHERE user = 'mcp_user' AND host = 'localhost';
84
- ```
85
-
86
- ### Best Practices
87
-
88
- 1. **Regular Password Rotation**
89
- - Change the MCP user's password periodically
90
- - Use strong, randomly generated passwords
91
- - Update application configurations after password changes
92
-
93
- 2. **Permission Review**
94
- - Regularly audit granted permissions
95
- - Remove unnecessary privileges
96
- - Keep permissions as restrictive as possible
97
-
98
- 3. **Access Patterns**
99
- - Monitor query patterns for potential issues
100
- - Set up alerts for unusual activity
101
- - Maintain detailed logs of database access
102
-
103
- 4. **Data Protection**
104
- - Consider encrypting sensitive columns
105
- - Use SSL/TLS for database connections (see **SSL/TLS Support** below)
106
- - Implement data masking where appropriate
107
-
108
- ### Secure Remote Access (SSH Tunneling)
109
-
110
- If your MySQL server is not on the same network as the MCP server, **do not expose MySQL directly to the internet.** Instead, use the built-in SSH tunneling support:
111
-
112
- 1. Enable SSH tunneling by setting `MYSQL_SSH_ENABLE=true`.
113
- 2. Configure your SSH jump host credentials and private key path.
114
- 3. The MCP server will establish a secure encrypted tunnel and connect to MySQL over `localhost`, keeping your database port closed to the outside world.
115
-
116
- ### SSL/TLS Support
117
-
118
- For production environments, always encrypt the connection between the MCP server and MySQL.
119
-
43
+ ```
44
+
45
+ 3. **Data Access Control**
46
+ - Grant access only to specific tables when possible
47
+ - Use column-level permissions for sensitive data:
48
+ ```sql
49
+ GRANT SELECT (public_column1, public_column2)
50
+ ON your_database.sensitive_table TO 'mcp_user'@'localhost';
51
+ ```
52
+
53
+ 4. **Regular Auditing**
54
+ - Enable MySQL audit logging for the MCP user
55
+ - Regularly review logs for unusual patterns
56
+ - Periodically review and adjust permissions
57
+
58
+ ### Environment Configuration
59
+
60
+ When setting up the MCP server, use these restricted credentials in your environment:
61
+
62
+ ```bash
63
+ MYSQL_USER=mcp_user
64
+ MYSQL_PASSWORD=your_secure_password
65
+ MYSQL_DATABASE=your_database
66
+ MYSQL_HOST=localhost
67
+ ```
68
+
69
+ ### Monitoring Usage
70
+
71
+ To monitor the MCP user's database usage:
72
+
73
+ ```sql
74
+ -- Check current connections
75
+ SELECT * FROM information_schema.PROCESSLIST
76
+ WHERE user = 'mcp_user';
77
+
78
+ -- View user privileges
79
+ SHOW GRANTS FOR 'mcp_user'@'localhost';
80
+
81
+ -- Check resource limits
82
+ SELECT * FROM mysql.user
83
+ WHERE user = 'mcp_user' AND host = 'localhost';
84
+ ```
85
+
86
+ ### Best Practices
87
+
88
+ 1. **Regular Password Rotation**
89
+ - Change the MCP user's password periodically
90
+ - Use strong, randomly generated passwords
91
+ - Update application configurations after password changes
92
+
93
+ 2. **Permission Review**
94
+ - Regularly audit granted permissions
95
+ - Remove unnecessary privileges
96
+ - Keep permissions as restrictive as possible
97
+
98
+ 3. **Access Patterns**
99
+ - Monitor query patterns for potential issues
100
+ - Set up alerts for unusual activity
101
+ - Maintain detailed logs of database access
102
+
103
+ 4. **Data Protection**
104
+ - Consider encrypting sensitive columns
105
+ - Use SSL/TLS for database connections (see **SSL/TLS Support** below)
106
+ - Implement data masking where appropriate
107
+
108
+ ### Secure Remote Access (SSH Tunneling)
109
+
110
+ If your MySQL server is not on the same network as the MCP server, **do not expose MySQL directly to the internet.** Instead, use the built-in SSH tunneling support:
111
+
112
+ 1. Enable SSH tunneling by setting `MYSQL_SSH_ENABLE=true`.
113
+ 2. Configure your SSH jump host credentials and private key path.
114
+ 3. The MCP server will establish a secure encrypted tunnel and connect to MySQL over `localhost`, keeping your database port closed to the outside world.
115
+
116
+ ### SSL/TLS Support
117
+
118
+ For production environments, always encrypt the connection between the MCP server and MySQL.
119
+
120
120
  Use the `MYSQL_SSL_MODE` environment variable to control encryption:
121
121
  - `DISABLED`: Allows plaintext only when explicitly selected; do not use in production.
122
122
  - `REQUIRED`: Ensures the connection is encrypted.
123
- - `VERIFY_CA`: Encrypts and verifies the server's certificate against a CA.
124
- - `VERIFY_IDENTITY`: Encrypts and verifies that the server's hostname matches the certificate.
125
-
123
+ - `VERIFY_CA`: Encrypts and verifies the server's certificate against a CA.
124
+ - `VERIFY_IDENTITY`: Encrypts and verifies that the server's hostname matches the certificate.
125
+
126
126
  `REQUIRED` is the default, and the MCP verifies after connection that the
127
127
  connector reports an encrypted session. Specify the CA certificate path using
128
128
  `MYSQL_SSL_CA` when using either verification mode.
129
-
129
+
130
130
  ### SQL Injection Protection
131
-
132
- The MCP server includes built-in protection against SQL injection for administrative operations:
133
- - All database and table identifiers provided via resources or tool arguments are strictly validated against a regex whitelist (`^[a-zA-Z0-9_$]+$`).
134
- - Identifiers are automatically quoted with backticks in internal queries.
131
+
132
+ The MCP server includes built-in protection against SQL injection for administrative operations:
133
+ - All database and table identifiers provided via resources or tool arguments are strictly validated against a regex whitelist (`^[a-zA-Z0-9_$]+$`).
134
+ - Identifiers are automatically quoted with backticks in internal queries.
135
135
  - `execute_sql` uses a lexer-style guard that ignores ordinary strings and comments but rejects MySQL `/*!...*/` and MariaDB `/*M!...*/` executable comments, multiple statements, DML, DDL, locks, transactions, `SELECT INTO`, and session assignment.
136
136
  - Stored functions and UDFs are fail-closed unless sqlglot recognizes them as a
137
137
  built-in or their reviewed name is explicitly listed in `allowed_functions`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yanzhang123/readonly-db-mcp",
3
- "version": "0.7.2",
3
+ "version": "0.7.3",
4
4
  "description": "Enterprise-auditable, strictly read-only MySQL MCP server with multi-environment profiles.",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",