mcp-dbutils 0.9.0__py3-none-any.whl → 0.10.0__py3-none-any.whl

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.
@@ -1,28 +1,35 @@
1
1
  """PostgreSQL configuration module"""
2
2
  from dataclasses import dataclass
3
3
  from typing import Optional, Dict, Any, Literal
4
- from urllib.parse import urlparse
4
+ from urllib.parse import urlparse, parse_qs
5
5
  from ..config import ConnectionConfig
6
6
 
7
- def parse_jdbc_url(jdbc_url: str) -> Dict[str, str]:
8
- """Parse JDBC URL into connection parameters
7
+ @dataclass
8
+ class SSLConfig:
9
+ """SSL configuration for PostgreSQL connection"""
10
+ mode: Literal['disable', 'require', 'verify-ca', 'verify-full'] = 'disable'
11
+ cert: Optional[str] = None
12
+ key: Optional[str] = None
13
+ root: Optional[str] = None
14
+
15
+ def parse_url(url: str) -> Dict[str, Any]:
16
+ """Parse PostgreSQL URL into connection parameters
9
17
 
10
18
  Args:
11
- jdbc_url: JDBC URL (e.g. jdbc:postgresql://host:port/dbname)
19
+ url: URL (e.g. postgresql://host:port/dbname?sslmode=verify-full)
12
20
 
13
21
  Returns:
14
- Dictionary of connection parameters
22
+ Dictionary of connection parameters including SSL settings
15
23
  """
16
- if not jdbc_url.startswith('jdbc:postgresql://'):
17
- raise ValueError("Invalid PostgreSQL JDBC URL format")
24
+ if not url.startswith('postgresql://'):
25
+ raise ValueError("Invalid PostgreSQL URL format")
18
26
 
19
- # Remove jdbc: prefix and ensure no credentials in URL
20
- url = jdbc_url[5:]
21
27
  if '@' in url:
22
- raise ValueError("JDBC URL should not contain credentials. Please provide username and password separately.")
28
+ raise ValueError("URL should not contain credentials. Please provide username and password separately.")
23
29
 
24
- # Parse URL
30
+ # Parse URL and query parameters
25
31
  parsed = urlparse(url)
32
+ query_params = parse_qs(parsed.query)
26
33
 
27
34
  params = {
28
35
  'host': parsed.hostname or 'localhost',
@@ -32,6 +39,24 @@ def parse_jdbc_url(jdbc_url: str) -> Dict[str, str]:
32
39
 
33
40
  if not params['dbname']:
34
41
  raise ValueError("PostgreSQL database name must be specified in URL")
42
+
43
+ # Parse SSL parameters if present
44
+ ssl_params = {}
45
+ if 'sslmode' in query_params:
46
+ mode = query_params['sslmode'][0]
47
+ if mode not in ['disable', 'require', 'verify-ca', 'verify-full']:
48
+ raise ValueError(f"Invalid sslmode: {mode}")
49
+ ssl_params['mode'] = mode
50
+
51
+ if 'sslcert' in query_params:
52
+ ssl_params['cert'] = query_params['sslcert'][0]
53
+ if 'sslkey' in query_params:
54
+ ssl_params['key'] = query_params['sslkey'][0]
55
+ if 'sslrootcert' in query_params:
56
+ ssl_params['root'] = query_params['sslrootcert'][0]
57
+
58
+ if ssl_params:
59
+ params['ssl'] = SSLConfig(**ssl_params)
35
60
 
36
61
  return params
37
62
 
@@ -44,6 +69,8 @@ class PostgreSQLConfig(ConnectionConfig):
44
69
  port: str = '5432'
45
70
  local_host: Optional[str] = None
46
71
  type: Literal['postgres'] = 'postgres'
72
+ url: Optional[str] = None
73
+ ssl: Optional[SSLConfig] = None
47
74
 
48
75
  @classmethod
49
76
  def from_yaml(cls, yaml_path: str, db_name: str, local_host: Optional[str] = None) -> 'PostgreSQLConfig':
@@ -74,9 +101,9 @@ class PostgreSQLConfig(ConnectionConfig):
74
101
  raise ValueError("Password must be specified in connection configuration")
75
102
 
76
103
  # Get connection parameters
77
- if 'jdbc_url' in db_config:
78
- # Parse JDBC URL for connection parameters
79
- params = parse_jdbc_url(db_config['jdbc_url'])
104
+ if 'url' in db_config:
105
+ # Parse URL for connection parameters
106
+ params = parse_url(db_config['url'])
80
107
  config = cls(
81
108
  dbname=params['dbname'],
82
109
  user=db_config['user'],
@@ -84,6 +111,8 @@ class PostgreSQLConfig(ConnectionConfig):
84
111
  host=params['host'],
85
112
  port=params['port'],
86
113
  local_host=local_host,
114
+ url=db_config['url'],
115
+ ssl=params.get('ssl')
87
116
  )
88
117
  else:
89
118
  if not db_config.get('dbname'):
@@ -92,6 +121,24 @@ class PostgreSQLConfig(ConnectionConfig):
92
121
  raise ValueError("Host must be specified in connection configuration")
93
122
  if not db_config.get('port'):
94
123
  raise ValueError("Port must be specified in connection configuration")
124
+
125
+ # Parse SSL configuration if present
126
+ ssl_config = None
127
+ if 'ssl' in db_config:
128
+ ssl_params = db_config['ssl']
129
+ if not isinstance(ssl_params, dict):
130
+ raise ValueError("SSL configuration must be a dictionary")
131
+
132
+ if ssl_params.get('mode') not in [None, 'disable', 'require', 'verify-ca', 'verify-full']:
133
+ raise ValueError(f"Invalid sslmode: {ssl_params.get('mode')}")
134
+
135
+ ssl_config = SSLConfig(
136
+ mode=ssl_params.get('mode', 'disable'),
137
+ cert=ssl_params.get('cert'),
138
+ key=ssl_params.get('key'),
139
+ root=ssl_params.get('root')
140
+ )
141
+
95
142
  config = cls(
96
143
  dbname=db_config['dbname'],
97
144
  user=db_config['user'],
@@ -99,17 +146,18 @@ class PostgreSQLConfig(ConnectionConfig):
99
146
  host=db_config['host'],
100
147
  port=str(db_config['port']),
101
148
  local_host=local_host,
149
+ ssl=ssl_config
102
150
  )
103
151
  config.debug = cls.get_debug_mode()
104
152
  return config
105
153
 
106
154
  @classmethod
107
- def from_jdbc_url(cls, jdbc_url: str, user: str, password: str,
108
- local_host: Optional[str] = None) -> 'PostgreSQLConfig':
109
- """Create configuration from JDBC URL and credentials
155
+ def from_url(cls, url: str, user: str, password: str,
156
+ local_host: Optional[str] = None) -> 'PostgreSQLConfig':
157
+ """Create configuration from URL and credentials
110
158
 
111
159
  Args:
112
- jdbc_url: JDBC URL (jdbc:postgresql://host:port/dbname)
160
+ url: URL (postgresql://host:port/dbname)
113
161
  user: Username for connection
114
162
  password: Password for connection
115
163
  local_host: Optional local host address
@@ -117,7 +165,7 @@ class PostgreSQLConfig(ConnectionConfig):
117
165
  Raises:
118
166
  ValueError: If URL format is invalid or required parameters are missing
119
167
  """
120
- params = parse_jdbc_url(jdbc_url)
168
+ params = parse_url(url)
121
169
 
122
170
  config = cls(
123
171
  dbname=params['dbname'],
@@ -126,6 +174,8 @@ class PostgreSQLConfig(ConnectionConfig):
126
174
  host=params['host'],
127
175
  port=params['port'],
128
176
  local_host=local_host,
177
+ url=url,
178
+ ssl=params.get('ssl')
129
179
  )
130
180
  config.debug = cls.get_debug_mode()
131
181
  return config
@@ -139,6 +189,17 @@ class PostgreSQLConfig(ConnectionConfig):
139
189
  'host': self.local_host or self.host,
140
190
  'port': self.port
141
191
  }
192
+
193
+ # Add SSL parameters if configured
194
+ if self.ssl:
195
+ params['sslmode'] = self.ssl.mode
196
+ if self.ssl.cert:
197
+ params['sslcert'] = self.ssl.cert
198
+ if self.ssl.key:
199
+ params['sslkey'] = self.ssl.key
200
+ if self.ssl.root:
201
+ params['sslrootcert'] = self.ssl.root
202
+
142
203
  return {k: v for k, v in params.items() if v}
143
204
 
144
205
  def get_masked_connection_info(self) -> Dict[str, Any]:
@@ -0,0 +1,227 @@
1
+ Metadata-Version: 2.4
2
+ Name: mcp-dbutils
3
+ Version: 0.10.0
4
+ Summary: MCP Database Utilities Service
5
+ Author: Dong Hao
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.10
9
+ Requires-Dist: mcp>=1.2.1
10
+ Requires-Dist: psycopg2-binary>=2.9.10
11
+ Requires-Dist: python-dotenv>=1.0.1
12
+ Requires-Dist: pyyaml>=6.0.2
13
+ Provides-Extra: test
14
+ Requires-Dist: aiosqlite>=0.19.0; extra == 'test'
15
+ Requires-Dist: docker>=7.0.0; extra == 'test'
16
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'test'
17
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'test'
18
+ Requires-Dist: pytest-docker>=2.0.0; extra == 'test'
19
+ Requires-Dist: pytest>=7.0.0; extra == 'test'
20
+ Requires-Dist: testcontainers>=3.7.0; extra == 'test'
21
+ Description-Content-Type: text/markdown
22
+
23
+ # MCP Database Utilities
24
+
25
+ ![GitHub Repo stars](https://img.shields.io/github/stars/donghao1393/mcp-dbutils)
26
+ ![PyPI version](https://img.shields.io/pypi/v/mcp-dbutils)
27
+ [![Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/donghao1393/bdd0a63ec2a816539ff8c136ceb41e48/raw/coverage.json)](https://github.com/donghao1393/mcp-dbutils/actions)
28
+ ![Python](https://img.shields.io/badge/Python-3.10%2B-blue)
29
+ ![License](https://img.shields.io/github/license/donghao1393/mcp-dbutils)
30
+ [![smithery badge](https://smithery.ai/badge/@donghao1393/mcp-dbutils)](https://smithery.ai/server/@donghao1393/mcp-dbutils)
31
+
32
+ [中文文档](README_CN.md)
33
+
34
+ ## Overview
35
+ MCP Database Utilities is a unified database access service that supports multiple database types (PostgreSQL and SQLite). Through its abstraction layer design, it provides a simple and unified database operation interface for MCP servers.
36
+
37
+ ## Features
38
+ - Unified database access interface
39
+ - Support for multiple database configurations
40
+ - Secure read-only query execution
41
+ - Table structure and schema information retrieval
42
+ - Database tables listing via MCP tools
43
+ - Intelligent connection management and resource cleanup
44
+ - Debug mode support
45
+ - SSL/TLS connection support for PostgreSQL
46
+
47
+ ## Installation and Configuration
48
+
49
+ ### Installation Methods
50
+ #### Installing via Smithery
51
+
52
+ To install Database Utilities for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@donghao1393/mcp-dbutils):
53
+
54
+ ```bash
55
+ npx -y @smithery/cli install @donghao1393/mcp-dbutils --client claude
56
+ ```
57
+
58
+ #### Using uvx (Recommended)
59
+ No installation required, run directly using `uvx`:
60
+ ```bash
61
+ uvx mcp-dbutils --config /path/to/config.yaml
62
+ ```
63
+
64
+ Add to Claude configuration:
65
+ ```json
66
+ "mcpServers": {
67
+ "mcp-dbutils": {
68
+ "command": "uvx",
69
+ "args": [
70
+ "mcp-dbutils",
71
+ "--config",
72
+ "/path/to/config.yaml"
73
+ ],
74
+ "env": {
75
+ "MCP_DEBUG": "1" // Optional: Enable debug mode
76
+ }
77
+ }
78
+ }
79
+ ```
80
+
81
+ #### Using pip
82
+ ```bash
83
+ pip install mcp-dbutils
84
+ ```
85
+
86
+ Add to Claude configuration:
87
+ ```json
88
+ "mcpServers": {
89
+ "mcp-dbutils": {
90
+ "command": "python",
91
+ "args": [
92
+ "-m",
93
+ "mcp_dbutils",
94
+ "--config",
95
+ "/path/to/config.yaml"
96
+ ],
97
+ "env": {
98
+ "MCP_DEBUG": "1" // Optional: Enable debug mode
99
+ }
100
+ }
101
+ }
102
+ ```
103
+
104
+ #### Using Docker
105
+ ```bash
106
+ docker run -i --rm \
107
+ -v /path/to/config.yaml:/app/config.yaml \
108
+ -v /path/to/sqlite.db:/app/sqlite.db \ # Optional: for SQLite database
109
+ -e MCP_DEBUG=1 \ # Optional: Enable debug mode
110
+ mcp/dbutils --config /app/config.yaml
111
+ ```
112
+
113
+ Add to Claude configuration:
114
+ ```json
115
+ "mcpServers": {
116
+ "mcp-dbutils": {
117
+ "command": "docker",
118
+ "args": [
119
+ "run",
120
+ "-i",
121
+ "--rm",
122
+ "-v",
123
+ "/path/to/config.yaml:/app/config.yaml",
124
+ "-v",
125
+ "/path/to/sqlite.db:/app/sqlite.db", // Optional: for SQLite database
126
+ "mcp/dbutils",
127
+ "--config",
128
+ "/app/config.yaml"
129
+ ],
130
+ "env": {
131
+ "MCP_DEBUG": "1" // Optional: Enable debug mode
132
+ }
133
+ }
134
+ }
135
+ ```
136
+
137
+ > **Note for Docker database connections:**
138
+ > - For SQLite: Mount your database file using `-v /path/to/sqlite.db:/app/sqlite.db`
139
+ > - For PostgreSQL running on host:
140
+ > - On Mac/Windows: Use `host.docker.internal` as host in config
141
+ > - On Linux: Use `172.17.0.1` (docker0 IP) or run with `--network="host"`
142
+
143
+ ### Requirements
144
+ - Python 3.10+
145
+ - PostgreSQL (optional)
146
+ - SQLite3 (optional)
147
+
148
+ ### Configuration File
149
+ The project requires a YAML configuration file, specified via the `--config` parameter. Configuration examples:
150
+
151
+ ```yaml
152
+ connections:
153
+ # SQLite configuration examples
154
+ dev-db:
155
+ type: sqlite
156
+ path: /path/to/dev.db
157
+ # Password is optional
158
+ password:
159
+
160
+ # PostgreSQL standard configuration
161
+ test-db:
162
+ type: postgres
163
+ host: postgres.example.com
164
+ port: 5432
165
+ dbname: test_db
166
+ user: test_user
167
+ password: test_pass
168
+
169
+ # PostgreSQL URL configuration with SSL
170
+ prod-db:
171
+ type: postgres
172
+ url: postgresql://postgres.example.com:5432/prod-db?sslmode=verify-full
173
+ user: prod_user
174
+ password: prod_pass
175
+
176
+ # PostgreSQL full SSL configuration example
177
+ secure-db:
178
+ type: postgres
179
+ host: secure-db.example.com
180
+ port: 5432
181
+ dbname: secure_db
182
+ user: secure_user
183
+ password: secure_pass
184
+ ssl:
185
+ mode: verify-full # disable/require/verify-ca/verify-full
186
+ cert: /path/to/client-cert.pem
187
+ key: /path/to/client-key.pem
188
+ root: /path/to/root.crt
189
+ ```
190
+
191
+ PostgreSQL SSL Configuration Options:
192
+ 1. Using URL parameters:
193
+ ```
194
+ postgresql://host:port/dbname?sslmode=verify-full&sslcert=/path/to/cert.pem
195
+ ```
196
+ 2. Using dedicated SSL configuration section:
197
+ ```yaml
198
+ ssl:
199
+ mode: verify-full # SSL verification mode
200
+ cert: /path/to/cert.pem # Client certificate
201
+ key: /path/to/key.pem # Client private key
202
+ root: /path/to/root.crt # CA certificate
203
+ ```
204
+
205
+ SSL Modes:
206
+ - disable: No SSL
207
+ - require: Use SSL but no certificate verification
208
+ - verify-ca: Verify server certificate is signed by trusted CA
209
+ - verify-full: Verify server certificate and hostname match
210
+
211
+ SQLite Configuration Options:
212
+ 1. Basic configuration with path:
213
+ ```yaml
214
+ type: sqlite
215
+ path: /path/to/db.sqlite
216
+ password: optional_password # Optional encryption
217
+ ```
218
+ 2. Using URI parameters:
219
+ ```yaml
220
+ type: sqlite
221
+ path: /path/to/db.sqlite?mode=ro&cache=shared
222
+ ```
223
+
224
+ ### Debug Mode
225
+ Set environment variable `MCP_DEBUG=1` to enable debug mode for detailed logging output.
226
+
227
+ [Rest of the README content remains unchanged...]
@@ -4,15 +4,15 @@ mcp_dbutils/config.py,sha256=uFI4Haw4en5gxHfCM9zugUqNCQFikdlHJZU_NTht7gQ,1905
4
4
  mcp_dbutils/log.py,sha256=fibVIwsb1HVU5zriGrDZTMEirKjgIuxuN_B_YTdAJ7I,996
5
5
  mcp_dbutils/stats.py,sha256=WYD9NAKHH2bFKmUSTOg18-SuIXergpznPq8AtIjtxdI,7101
6
6
  mcp_dbutils/postgres/__init__.py,sha256=XanCXw-kVE6ayqFqjuLJ9swWPcCVlcKZXB2Et2Wjl9w,154
7
- mcp_dbutils/postgres/config.py,sha256=Kqq0ZCa7PhtvMaBX3sfdEscGosHR1dWuiP8IkI5lzDo,5495
7
+ mcp_dbutils/postgres/config.py,sha256=FG0YUV4TtP1IGZT87ov_PK-ouOEjAOHdSaK42klk5OE,7750
8
8
  mcp_dbutils/postgres/handler.py,sha256=O45K0MOosNQ68SJ8piXXH3aZ74RVQ981hudk6faj28Y,24397
9
9
  mcp_dbutils/postgres/server.py,sha256=FROogvjr3xlKAZcAvJMNHGgyHqT_LaMK9-vYbA0Dbm0,8716
10
10
  mcp_dbutils/sqlite/__init__.py,sha256=lTUOkSfSWNw_BohJ_KNxYKMCANdtpGa3JK_ZyJsg_Ls,134
11
11
  mcp_dbutils/sqlite/config.py,sha256=2ekTp89rcCu4qQN1O3sZjIcOwjhzWi4tisD20T2WAik,4533
12
12
  mcp_dbutils/sqlite/handler.py,sha256=VxBVbwpNSQHyiudQXYFYpcdoScvbK2IGzYMbkcpvFcI,17731
13
13
  mcp_dbutils/sqlite/server.py,sha256=49ug43nyXZApclMXo0t5dKCN4wjDyDUZ-vmf746ac8M,7709
14
- mcp_dbutils-0.9.0.dist-info/METADATA,sha256=I52Q7IV8un9A5tmTTmEOFKZiW_UYCrWwBDhDq1tzFyE,11986
15
- mcp_dbutils-0.9.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
- mcp_dbutils-0.9.0.dist-info/entry_points.txt,sha256=XTjt0QmYRgKOJQT6skR9bp1EMUfIrgpHeZJPZ3CJffs,49
17
- mcp_dbutils-0.9.0.dist-info/licenses/LICENSE,sha256=1A_CwpWVlbjrKdVEYO77vYfnXlW7oxcilZ8FpA_BzCI,1065
18
- mcp_dbutils-0.9.0.dist-info/RECORD,,
14
+ mcp_dbutils-0.10.0.dist-info/METADATA,sha256=TC_KrWktHUIG6vznvxhIsz-pJG_WWxgH8s1HQJO7NgQ,6262
15
+ mcp_dbutils-0.10.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
+ mcp_dbutils-0.10.0.dist-info/entry_points.txt,sha256=XTjt0QmYRgKOJQT6skR9bp1EMUfIrgpHeZJPZ3CJffs,49
17
+ mcp_dbutils-0.10.0.dist-info/licenses/LICENSE,sha256=1A_CwpWVlbjrKdVEYO77vYfnXlW7oxcilZ8FpA_BzCI,1065
18
+ mcp_dbutils-0.10.0.dist-info/RECORD,,
@@ -1,392 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: mcp-dbutils
3
- Version: 0.9.0
4
- Summary: MCP Database Utilities Service
5
- Author: Dong Hao
6
- License-Expression: MIT
7
- License-File: LICENSE
8
- Requires-Python: >=3.10
9
- Requires-Dist: mcp>=1.2.1
10
- Requires-Dist: psycopg2-binary>=2.9.10
11
- Requires-Dist: python-dotenv>=1.0.1
12
- Requires-Dist: pyyaml>=6.0.2
13
- Provides-Extra: test
14
- Requires-Dist: aiosqlite>=0.19.0; extra == 'test'
15
- Requires-Dist: docker>=7.0.0; extra == 'test'
16
- Requires-Dist: pytest-asyncio>=0.23.0; extra == 'test'
17
- Requires-Dist: pytest-cov>=4.1.0; extra == 'test'
18
- Requires-Dist: pytest-docker>=2.0.0; extra == 'test'
19
- Requires-Dist: pytest>=7.0.0; extra == 'test'
20
- Requires-Dist: testcontainers>=3.7.0; extra == 'test'
21
- Description-Content-Type: text/markdown
22
-
23
- # MCP Database Utilities
24
-
25
- ![GitHub Repo stars](https://img.shields.io/github/stars/donghao1393/mcp-dbutils)
26
- ![PyPI version](https://img.shields.io/pypi/v/mcp-dbutils)
27
- [![Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/donghao1393/bdd0a63ec2a816539ff8c136ceb41e48/raw/coverage.json)](https://github.com/donghao1393/mcp-dbutils/actions)
28
- ![Python](https://img.shields.io/badge/Python-3.10%2B-blue)
29
- ![License](https://img.shields.io/github/license/donghao1393/mcp-dbutils)
30
- [![smithery badge](https://smithery.ai/badge/@donghao1393/mcp-dbutils)](https://smithery.ai/server/@donghao1393/mcp-dbutils)
31
-
32
- [中文文档](README_CN.md)
33
-
34
- ## Overview
35
- MCP Database Utilities is a unified database access service that supports multiple database types (PostgreSQL and SQLite). Through its abstraction layer design, it provides a simple and unified database operation interface for MCP servers.
36
-
37
- ## Features
38
- - Unified database access interface
39
- - Support for multiple database configurations
40
- - Secure read-only query execution
41
- - Table structure and schema information retrieval
42
- - Database tables listing via MCP tools
43
- - Intelligent connection management and resource cleanup
44
- - Debug mode support
45
-
46
- ## Installation and Configuration
47
-
48
- ### Installation Methods
49
- #### Installing via Smithery
50
-
51
- To install Database Utilities for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@donghao1393/mcp-dbutils):
52
-
53
- ```bash
54
- npx -y @smithery/cli install @donghao1393/mcp-dbutils --client claude
55
- ```
56
-
57
- #### Using uvx (Recommended)
58
- No installation required, run directly using `uvx`:
59
- ```bash
60
- uvx mcp-dbutils --config /path/to/config.yaml
61
- ```
62
-
63
- Add to Claude configuration:
64
- ```json
65
- "mcpServers": {
66
- "mcp-dbutils": {
67
- "command": "uvx",
68
- "args": [
69
- "mcp-dbutils",
70
- "--config",
71
- "/path/to/config.yaml"
72
- ],
73
- "env": {
74
- "MCP_DEBUG": "1" // Optional: Enable debug mode
75
- }
76
- }
77
- }
78
- ```
79
-
80
- #### Using pip
81
- ```bash
82
- pip install mcp-dbutils
83
- ```
84
-
85
- Add to Claude configuration:
86
- ```json
87
- "mcpServers": {
88
- "mcp-dbutils": {
89
- "command": "python",
90
- "args": [
91
- "-m",
92
- "mcp_dbutils",
93
- "--config",
94
- "/path/to/config.yaml"
95
- ],
96
- "env": {
97
- "MCP_DEBUG": "1" // Optional: Enable debug mode
98
- }
99
- }
100
- }
101
- ```
102
-
103
- #### Using Docker
104
- ```bash
105
- docker run -i --rm \
106
- -v /path/to/config.yaml:/app/config.yaml \
107
- -v /path/to/sqlite.db:/app/sqlite.db \ # Optional: for SQLite database
108
- -e MCP_DEBUG=1 \ # Optional: Enable debug mode
109
- mcp/dbutils --config /app/config.yaml
110
- ```
111
-
112
- Add to Claude configuration:
113
- ```json
114
- "mcpServers": {
115
- "mcp-dbutils": {
116
- "command": "docker",
117
- "args": [
118
- "run",
119
- "-i",
120
- "--rm",
121
- "-v",
122
- "/path/to/config.yaml:/app/config.yaml",
123
- "-v",
124
- "/path/to/sqlite.db:/app/sqlite.db", // Optional: for SQLite database
125
- "mcp/dbutils",
126
- "--config",
127
- "/app/config.yaml"
128
- ],
129
- "env": {
130
- "MCP_DEBUG": "1" // Optional: Enable debug mode
131
- }
132
- }
133
- }
134
- ```
135
-
136
- > **Note for Docker database connections:**
137
- > - For SQLite: Mount your database file using `-v /path/to/sqlite.db:/app/sqlite.db`
138
- > - For PostgreSQL running on host:
139
- > - On Mac/Windows: Use `host.docker.internal` as host in config
140
- > - On Linux: Use `172.17.0.1` (docker0 IP) or run with `--network="host"`
141
-
142
- ### Requirements
143
- - Python 3.10+
144
- - PostgreSQL (optional)
145
- - SQLite3 (optional)
146
-
147
- ### Configuration File
148
- The project requires a YAML configuration file, specified via the `--config` parameter. Configuration example:
149
-
150
- ```yaml
151
- connections:
152
- # Standard PostgreSQL configuration example
153
- my_postgres:
154
- type: postgres
155
- dbname: test_db
156
- user: postgres
157
- password: secret
158
- host: host.docker.internal # For Mac/Windows
159
- # host: 172.17.0.1 # For Linux (docker0 IP)
160
- port: 5432
161
-
162
- # PostgreSQL with JDBC URL example
163
- my_postgres_jdbc:
164
- type: postgres
165
- jdbc_url: jdbc:postgresql://host.docker.internal:5432/test_db
166
- user: postgres # Credentials must be provided separately
167
- password: secret # Not included in JDBC URL for security
168
-
169
- # SQLite standard configuration
170
- my_sqlite:
171
- type: sqlite
172
- path: /app/sqlite.db # Database file path
173
- password: optional_password # optional
174
-
175
- # SQLite with JDBC URL configuration
176
- my_sqlite_jdbc:
177
- type: sqlite
178
- jdbc_url: jdbc:sqlite:/app/data.db?mode=ro&cache=shared # Supports query parameters
179
- password: optional_password # Provided separately for security
180
- ```
181
-
182
- The configuration supports JDBC URL format for both PostgreSQL and SQLite:
183
-
184
- PostgreSQL:
185
- 1. Standard configuration with individual parameters
186
- 2. JDBC URL configuration with separate credentials
187
-
188
- SQLite:
189
- 1. Standard configuration with path parameter
190
- 2. JDBC URL configuration with query parameters support:
191
- - mode=ro: Read-only mode
192
- - cache=shared: Shared cache mode
193
- - Other SQLite URI parameters
194
-
195
- ### Debug Mode
196
- Set environment variable `MCP_DEBUG=1` to enable debug mode for detailed logging output.
197
-
198
- ## Architecture Design
199
-
200
- ### Core Concept: Abstraction Layer
201
-
202
- ```mermaid
203
- graph TD
204
- Client[Client] --> DatabaseServer[Database Server]
205
- subgraph MCP Server
206
- DatabaseServer
207
- DatabaseHandler[Database Handler]
208
- PostgresHandler[PostgreSQL Handler]
209
- SQLiteHandler[SQLite Handler]
210
- DatabaseServer --> DatabaseHandler
211
- DatabaseHandler --> PostgresHandler
212
- DatabaseHandler --> SQLiteHandler
213
- end
214
- PostgresHandler --> PostgreSQL[(PostgreSQL)]
215
- SQLiteHandler --> SQLite[(SQLite)]
216
- ```
217
-
218
- The abstraction layer design is the core architectural concept in MCP Database Utilities. Just like a universal remote control that works with different devices, users only need to know the basic operations without understanding the underlying complexities.
219
-
220
- #### 1. Simplified User Interaction
221
- - Users only need to know the database configuration name (e.g., "my_postgres")
222
- - No need to deal with connection parameters and implementation details
223
- - MCP server automatically handles database connections and queries
224
-
225
- #### 2. Unified Interface Design
226
- - DatabaseHandler abstract class defines unified operation interfaces
227
- - All specific database implementations (PostgreSQL/SQLite) follow the same interface
228
- - Users interact with different databases in the same way
229
-
230
- #### 3. Configuration and Implementation Separation
231
- - Complex database configuration parameters are encapsulated in configuration files
232
- - Runtime access through simple database names
233
- - Easy management and modification of database configurations without affecting business code
234
-
235
- ### System Components
236
- 1. DatabaseServer
237
- - Core component of the MCP server
238
- - Handles resource and tool requests
239
- - Manages database connection lifecycle
240
-
241
- 2. DatabaseHandler
242
- - Abstract base class defining unified interface
243
- - Includes get_tables(), get_schema(), execute_query(), etc.
244
- - Implemented by PostgreSQL and SQLite handlers
245
-
246
- 3. Configuration System
247
- - YAML-based configuration file
248
- - Support for multiple database configurations
249
- - Type-safe configuration validation
250
-
251
- 4. Error Handling and Logging
252
- - Unified error handling mechanism
253
- - Detailed logging output
254
- - Sensitive information masking
255
-
256
- ## Usage Examples
257
-
258
- ### Basic Query
259
- ```python
260
- # Access through connection name
261
- async with server.get_handler("my_postgres") as handler:
262
- # Execute SQL query
263
- result = await handler.execute_query("SELECT * FROM users")
264
- ```
265
-
266
- ### View Table Structure
267
- ```python
268
- # Get all tables
269
- tables = await handler.get_tables()
270
-
271
- # Get specific table schema
272
- schema = await handler.get_schema("users")
273
- ```
274
-
275
- ### Error Handling
276
- ```python
277
- try:
278
- async with server.get_handler("my_connection") as handler:
279
- result = await handler.execute_query("SELECT * FROM users")
280
- except ValueError as e:
281
- print(f"Configuration error: {e}")
282
- except Exception as e:
283
- print(f"Query error: {e}")
284
- ```
285
-
286
- ## Security Notes
287
- - Supports SELECT queries only to protect database security
288
- - Automatically masks sensitive information (like passwords) in logs
289
- - Executes queries in read-only transactions
290
-
291
- ## API Documentation
292
-
293
- ### DatabaseServer
294
- Core server class providing:
295
- - Resource list retrieval
296
- - Tool call handling (list_tables, query)
297
- - Database handler management
298
-
299
- ### MCP Tools
300
-
301
- #### dbutils-list-tables
302
- Lists all tables in the specified database.
303
- - Parameters:
304
- * connection: Database connection name
305
- - Returns: Text content with a list of table names
306
-
307
- #### dbutils-run-query
308
- Executes a SQL query on the specified database.
309
- - Parameters:
310
- * connection: Database connection name
311
- * sql: SQL query to execute (SELECT only)
312
- - Returns: Query results in a formatted text
313
-
314
- #### dbutils-get-stats
315
- Get table statistics information.
316
- - Parameters:
317
- * connection: Database connection name
318
- * table: Table name
319
- - Returns: Statistics including row count, size, column stats
320
-
321
- #### dbutils-list-constraints
322
- List table constraints (primary key, foreign keys, etc).
323
- - Parameters:
324
- * connection: Database connection name
325
- * table: Table name
326
- - Returns: Detailed constraint information
327
-
328
- #### dbutils-explain-query
329
- Get query execution plan with cost estimates.
330
- - Parameters:
331
- * connection: Database connection name
332
- * sql: SQL query to explain
333
- - Returns: Formatted execution plan
334
-
335
- #### dbutils-get-performance
336
- Get database performance statistics.
337
- - Parameters:
338
- * connection: Database connection name
339
- - Returns: Detailed performance statistics including query times, query types, error rates, and resource usage
340
-
341
- #### dbutils-analyze-query
342
- Analyze a SQL query for performance and provide optimization suggestions.
343
- - Parameters:
344
- * connection: Database connection name
345
- * sql: SQL query to analyze
346
- - Returns: Query analysis with execution plan, timing information, and optimization suggestions
347
-
348
- ### DatabaseHandler
349
- Abstract base class defining interfaces:
350
- - get_tables(): Get table resource list
351
- - get_schema(): Get table structure
352
- - execute_query(): Execute SQL query
353
- - cleanup(): Resource cleanup
354
-
355
- ### PostgreSQL Implementation
356
- Provides PostgreSQL-specific features:
357
- - Remote connection support
358
- - Table description information
359
- - Constraint queries
360
-
361
- ### SQLite Implementation
362
- Provides SQLite-specific features:
363
- - File path handling
364
- - URI scheme support
365
- - Password protection support (optional)
366
-
367
- ## Contributing
368
- Contributions are welcome! Here's how you can help:
369
-
370
- 1. 🐛 Report bugs: Open an issue describing the bug and how to reproduce it
371
- 2. 💡 Suggest features: Open an issue to propose new features
372
- 3. 🛠️ Submit PRs: Fork the repo and create a pull request with your changes
373
-
374
- ### Development Setup
375
- 1. Clone the repository
376
- 2. Create a virtual environment using `uv venv`
377
- 3. Install dependencies with `uv sync --all-extras`
378
- 4. Run tests with `pytest`
379
-
380
- For detailed guidelines, see [CONTRIBUTING.md](.github/CONTRIBUTING.md)
381
-
382
- ## Acknowledgments
383
- - [MCP Servers](https://github.com/modelcontextprotocol/servers) for inspiration and demonstration
384
- - AI Editors:
385
- * [Claude Desktop](https://claude.ai/download)
386
- * [5ire](https://5ire.app/)
387
- * [Cline](https://cline.bot)
388
- - [Model Context Protocol](https://modelcontextprotocol.io/) for comprehensive interfaces
389
-
390
- ## Star History
391
-
392
- [![Star History Chart](https://api.star-history.com/svg?repos=donghao1393/mcp-dbutils&type=Date)](https://star-history.com/#donghao1393/mcp-dbutils&Date)