Skip to content

Commit 5fe1cb8

Browse files
committed
docs: add CLICKHOUSE_TLS_MODE documentation
- Add CLICKHOUSE_TLS_MODE to README mTLS section with valid options - Update ClickHouseConfig docstring with TLS_MODE variable feat: add CLICKHOUSE_TLS_MODE support for proxy/strict modes docs: add mTLS configuration documentation Document new environment variables for mutual TLS authentication: - CLICKHOUSE_CA_CERT - CLICKHOUSE_CLIENT_CERT - CLICKHOUSE_CLIENT_CERT_KEY Include example configuration for mTLS setup. feat: add mTLS (mutual TLS) support Add support for client certificate authentication (mTLS) via new environment variables: - CLICKHOUSE_CA_CERT: Path to CA certificate file - CLICKHOUSE_CLIENT_CERT: Path to client certificate file - CLICKHOUSE_CLIENT_CERT_KEY: Path to client private key file These parameters are passed to clickhouse-connect's get_client() function to enable secure connections to ClickHouse servers that require mutual TLS authentication.
1 parent 4f659f2 commit 5fe1cb8

2 files changed

Lines changed: 131 additions & 1 deletion

File tree

README.md

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ The following environment variables are used to configure the ClickHouse and chD
308308
* `CLICKHOUSE_VERIFY`: Enable/disable SSL certificate verification
309309
* Default: `"true"`
310310
* Set to `"false"` to disable certificate verification (not recommended for production)
311-
* TLS certificates: The package uses your operating system trust store for TLS certificate verification via `truststore`. We call `truststore.inject_into_ssl()` at startup to ensure proper certificate handling. Pythons default SSL behavior is used as a fallback only if an unexpected error occurs.
311+
* TLS certificates: The package uses your operating system trust store for TLS certificate verification via `truststore`. We call `truststore.inject_into_ssl()` at startup to ensure proper certificate handling. Python's default SSL behavior is used as a fallback only if an unexpected error occurs.
312312
* `CLICKHOUSE_CONNECT_TIMEOUT`: Connection timeout in seconds
313313
* Default: `"30"`
314314
* Increase this value if you experience connection timeouts
@@ -335,6 +335,30 @@ The following environment variables are used to configure the ClickHouse and chD
335335
* Default: `"true"`
336336
* Set to `"false"` to disable ClickHouse tools when using chDB only
337337

338+
##### mTLS (Mutual TLS) Variables
339+
340+
These variables enable client certificate authentication for ClickHouse servers that require mutual TLS:
341+
342+
* `CLICKHOUSE_CA_CERT`: Path to CA certificate file
343+
* Default: None
344+
* Set this to specify a custom CA certificate for SSL verification
345+
* Example: `/path/to/ca.crt`
346+
* `CLICKHOUSE_CLIENT_CERT`: Path to client certificate file
347+
* Default: None
348+
* Required for mTLS authentication
349+
* Can be a `.pem` file containing both the certificate and private key
350+
* Example: `/path/to/client.crt` or `/path/to/client.pem`
351+
* `CLICKHOUSE_CLIENT_CERT_KEY`: Path to client private key file
352+
* Default: None
353+
* Optional if `CLICKHOUSE_CLIENT_CERT` is a `.pem` file containing both the certificate and private key
354+
* Example: `/path/to/client.key`
355+
* `CLICKHOUSE_TLS_MODE`: TLS mode for client certificate authentication
356+
* Default: None (auto-detected based on `CLICKHOUSE_CLIENT_CERT`)
357+
* Valid options:
358+
* `"mutual"` - Use client certificate for authentication (default when `CLICKHOUSE_CLIENT_CERT` is set)
359+
* `"proxy"` - TLS termination at proxy, use Basic Auth with client certs for TLS only
360+
* `"strict"` - Strict TLS mode with Basic Auth
361+
338362
#### chDB Variables
339363

340364
* `CHDB_ENABLED`: Enable/disable chDB functionality
@@ -382,6 +406,55 @@ CLICKHOUSE_PASSWORD=
382406
# Uses secure defaults (HTTPS on port 8443)
383407
```
384408

409+
For ClickHouse with mTLS (Mutual TLS):
410+
411+
```env
412+
# Required variables
413+
CLICKHOUSE_HOST=your-secure-clickhouse.example.com
414+
CLICKHOUSE_PORT=8443
415+
CLICKHOUSE_USER=your-user
416+
CLICKHOUSE_PASSWORD=your-password
417+
418+
# mTLS configuration
419+
CLICKHOUSE_SECURE=true
420+
CLICKHOUSE_CA_CERT=/path/to/ca.crt
421+
CLICKHOUSE_CLIENT_CERT=/path/to/client.crt
422+
CLICKHOUSE_CLIENT_CERT_KEY=/path/to/client.key
423+
424+
# Or if using a combined .pem file:
425+
# CLICKHOUSE_CLIENT_CERT=/path/to/client.pem
426+
```
427+
428+
Example Claude Desktop configuration with mTLS:
429+
430+
```json
431+
{
432+
"mcpServers": {
433+
"mcp-clickhouse": {
434+
"command": "uv",
435+
"args": [
436+
"run",
437+
"--with",
438+
"mcp-clickhouse",
439+
"--python",
440+
"3.10",
441+
"mcp-clickhouse"
442+
],
443+
"env": {
444+
"CLICKHOUSE_HOST": "your-secure-clickhouse.example.com",
445+
"CLICKHOUSE_PORT": "8443",
446+
"CLICKHOUSE_USER": "your-user",
447+
"CLICKHOUSE_PASSWORD": "your-password",
448+
"CLICKHOUSE_SECURE": "true",
449+
"CLICKHOUSE_CA_CERT": "/path/to/ca.crt",
450+
"CLICKHOUSE_CLIENT_CERT": "/path/to/client.crt",
451+
"CLICKHOUSE_CLIENT_CERT_KEY": "/path/to/client.key"
452+
}
453+
}
454+
}
455+
}
456+
```
457+
385458
For chDB only (in-memory):
386459

387460
```env

mcp_clickhouse/mcp_env.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ class ClickHouseConfig:
4545
CLICKHOUSE_DATABASE: Default database to use (default: None)
4646
CLICKHOUSE_PROXY_PATH: Path to be added to the host URL. For instance, for servers behind an HTTP proxy (default: None)
4747
CLICKHOUSE_ENABLED: Enable ClickHouse server (default: true)
48+
CLICKHOUSE_CA_CERT: Path to CA certificate file for SSL verification (default: None)
49+
CLICKHOUSE_CLIENT_CERT: Path to client certificate file for mTLS authentication (default: None)
50+
CLICKHOUSE_CLIENT_CERT_KEY: Path to client private key file for mTLS authentication (default: None)
51+
CLICKHOUSE_TLS_MODE: TLS mode for client certificate usage - "mutual", "proxy", or "strict" (default: None)
4852
"""
4953

5054
def __init__(self):
@@ -132,6 +136,46 @@ def send_receive_timeout(self) -> int:
132136
def proxy_path(self) -> str:
133137
return os.getenv("CLICKHOUSE_PROXY_PATH")
134138

139+
@property
140+
def ca_cert(self) -> Optional[str]:
141+
"""Get the path to CA certificate file for SSL verification.
142+
143+
Default: None
144+
"""
145+
return os.getenv("CLICKHOUSE_CA_CERT")
146+
147+
@property
148+
def client_cert(self) -> Optional[str]:
149+
"""Get the path to client certificate file for mTLS authentication.
150+
151+
Default: None
152+
"""
153+
return os.getenv("CLICKHOUSE_CLIENT_CERT")
154+
155+
@property
156+
def client_cert_key(self) -> Optional[str]:
157+
"""Get the path to client private key file for mTLS authentication.
158+
159+
This is optional if the client_cert file contains both the certificate
160+
and the private key (e.g., a combined .pem file).
161+
162+
Default: None
163+
"""
164+
return os.getenv("CLICKHOUSE_CLIENT_CERT_KEY")
165+
166+
@property
167+
def tls_mode(self) -> Optional[str]:
168+
"""Get the TLS mode for client certificate usage.
169+
170+
Valid values:
171+
- 'mutual': Use client certificate for authentication (default when client_cert is set)
172+
- 'proxy': TLS termination at proxy, use Basic Auth with client certs for TLS only
173+
- 'strict': Strict TLS mode, use Basic Auth with client certs for TLS only
174+
175+
Default: None (auto-detected by clickhouse-connect)
176+
"""
177+
return os.getenv("CLICKHOUSE_TLS_MODE")
178+
135179
def get_client_config(self) -> dict:
136180
"""Get the configuration dictionary for clickhouse_connect client.
137181
@@ -162,6 +206,19 @@ def get_client_config(self) -> dict:
162206
if self.proxy_path:
163207
config["proxy_path"] = self.proxy_path
164208

209+
# Add mTLS configuration if set
210+
if self.ca_cert:
211+
config["ca_cert"] = self.ca_cert
212+
213+
if self.client_cert:
214+
config["client_cert"] = self.client_cert
215+
216+
if self.client_cert_key:
217+
config["client_cert_key"] = self.client_cert_key
218+
219+
if self.tls_mode:
220+
config["tls_mode"] = self.tls_mode
221+
165222
return config
166223

167224
def _validate_required_vars(self) -> None:

0 commit comments

Comments
 (0)